condition
import { condition } from "patronum";// orimport { condition } from "patronum/condition";Motivation
Condition is very similar to sample, but allows you to have else branch
along with simple if matcher. At least one of then or else is required;
throws if both are omitted.
condition({ source: Unit, if: Store, then?: Unit | Unit[], else?: Unit | Unit[] })
Formulae
result = condition({ source, if: $checker, then, else,});- When
sourceis triggered, check value of$checker, if it equalstrue, triggerthenwith value fromsource, otherwise triggerelsewith value fromsource resultis the same unit assourceallows to nestconditionto anotherconditionorsample
Arguments
source(Unit<T>)— Data from this unit will be passed tothenorelseif(Store<boolean>)— Updates of this store will not triggerthenandelsethen(UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>)— Target unit(s) triggered with data fromsourceif$checkercontainstrue. Required ifelseis not providedelse(UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>)— Target unit(s) triggered with data fromsourceif$checkercontainsfalse. Required ifthenis not provided
If
then/elseis an array, every target in the array will be triggered. The array is not deduplicated: the same unit repeated multiple times will be triggered multiple times.
Returns
(Unit<T>)— The same unit type that passed tosource
Example
const change = createEvent();const $source = createStore("data");
const toggle = createEvent();const $isEnabled = createStore(false);
const enabled = createEvent();const disabled = createEvent();
$source.on(change, (_, payload) => payload);$isEnabled.on(toggle, (is) => !is);
condition({ source: $source, if: $isEnabled, then: enabled, else: disabled,});enabled.watch((payload) => console.log("enabled -", payload));disabled.watch((payload) => console.log("disabled -", payload));
change("newdata");// => disabled - newdata
toggle();change("data");// => enabled - datacondition({ source: Unit<T>, if: T, then?: Unit | Unit[], else?: Unit | Unit[] })
Formulae
result = condition({ source, if: value, then, else,});- When
sourceis triggered, comparevalueliteral withsourcepayload, if it equals triggerthenwith value fromsource, otherwise triggerelsewith value fromsource resultis the same unit assourceallows to nestconditionto anotherconditionorsample
Arguments
source(Unit<T>)— Data from this unit will be passed tothenorelseif(T)— Just value to compare withsourcepayload. Note: objects will be compared by referencethen(UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>)— Target unit(s) triggered with data fromsourceif payload equalsifvalue. Required ifelseis not providedelse(UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>)— Target unit(s) triggered with data fromsourceif payload does not equalifvalue. Required ifthenis not provided
Returns
(Unit<T>)— The same unit type that passed tosource
Example
const increment = createEvent();const $source = createStore(0);
const log = createEvent();const run = createEffect((data) => { console.info("FAKE RUN EFFECT", data);});
$source.on(increment, (state) => state + 1);
condition({ source: $source, if: 4, then: run, else: log,});
log.watch((payload) => console.log("LOG ABOUT IT", payload));
increment(); // => LOG ABOUT IT 1increment(); // => LOG ABOUT IT 2increment(); // => LOG ABOUT IT 3increment(); // => FAKE RUN EFFECT 4increment(); // => LOG ABOUT IT 5condition({ source: Unit<T>, if: Function, then?: Unit | Unit[], else?: Unit | Unit[] })
Formulae
result = condition({ source, if: (payload) => boolean, then, else,});- When
sourceis triggered, callifwithsourcepayload, if it returnstruetriggerthenwith value fromsource, otherwise triggerelsewith value fromsource resultis the same unit assourceallows to nestconditionto anotherconditionorsample
Arguments
source(Unit<T>)— Data from this unit will be passed tothenorelseif((payload: T) => boolean)— Function comparator. It should return booleanthen(UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>)— Target unit(s) triggered with data fromsourceif comparator returnstrue. Required ifelseis not providedelse(UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>)— Target unit(s) triggered with data fromsourceif comparator returnsfalse. Required ifthenis not provided
Returns
(Unit<T>)— The same unit type that passed tosource
Example
const change = createEvent();const $source = createStore("data");const target = createEvent();const another = createEvent();
$source.on(change, (_, payload) => payload);
condition({ source: $source, if: (source) => source.length > 3, then: target, else: another,});target.watch((payload) => console.log("triggered", payload));another.watch((payload) => console.log("condition else:", payload));
change("newdata");// => triggered newdata
change("old");// => condition else: oldExamples
Source is event
const inputChanged = createEvent();const $value = createStore("");const $error = createStore(false);
const setError = createEvent();const setValue = createEvent();
$value.on(setValue, (_, value) => value);$error.on(setError, () => true);$error.on(setValue, () => false);
condition({ source: inputChanged, if: isValid, then: setValue, else: setError,});
function isValid(value) { return value.trim().length > 0;}Condition can be nested
const $value = createStore("hello@world");const updateEmail = createEvent<string>();
condition({ source: $value, if: (length) => length > 0, then: condition({ if: (string) => string.includes("@"), then: updateEmail, }),});Multiple targets in then/else
const inputChanged = createEvent<string>();const $isValid = createStore(false);
const save = createEvent<string>();const track = createEvent<string>();const showError = createEvent<string>();
condition({ source: inputChanged, if: $isValid, then: [save, track], else: [showError],});