Skip to content

condition

import { condition } from "patronum";
// or
import { 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 source is triggered, check value of $checker, if it equals true, trigger then with value from source, otherwise trigger else with value from source
  • result is the same unit as source allows to nest condition to another condition or sample

Arguments

  1. source (Unit<T>) — Data from this unit will be passed to then or else
  2. if (Store<boolean>) — Updates of this store will not trigger then and else
  3. then (UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>) — Target unit(s) triggered with data from source if $checker contains true. Required if else is not provided
  4. else (UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>) — Target unit(s) triggered with data from source if $checker contains false. Required if then is not provided

If then/else is 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

  1. (Unit<T>) — The same unit type that passed to source

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 - data

condition({ source: Unit<T>, if: T, then?: Unit | Unit[], else?: Unit | Unit[] })

Formulae

result = condition({
source,
if: value,
then,
else,
});
  • When source is triggered, compare value literal with source payload, if it equals trigger then with value from source, otherwise trigger else with value from source
  • result is the same unit as source allows to nest condition to another condition or sample

Arguments

  1. source (Unit<T>) — Data from this unit will be passed to then or else
  2. if (T) — Just value to compare with source payload. Note: objects will be compared by reference
  3. then (UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>) — Target unit(s) triggered with data from source if payload equals if value. Required if else is not provided
  4. else (UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>) — Target unit(s) triggered with data from source if payload does not equal if value. Required if then is not provided

Returns

  1. (Unit<T>) — The same unit type that passed to source

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 1
increment(); // => LOG ABOUT IT 2
increment(); // => LOG ABOUT IT 3
increment(); // => FAKE RUN EFFECT 4
increment(); // => LOG ABOUT IT 5

condition({ source: Unit<T>, if: Function, then?: Unit | Unit[], else?: Unit | Unit[] })

Formulae

result = condition({
source,
if: (payload) => boolean,
then,
else,
});
  • When source is triggered, call if with source payload, if it returns true trigger then with value from source, otherwise trigger else with value from source
  • result is the same unit as source allows to nest condition to another condition or sample

Arguments

  1. source (Unit<T>) — Data from this unit will be passed to then or else
  2. if ((payload: T) => boolean) — Function comparator. It should return boolean
  3. then (UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>) — Target unit(s) triggered with data from source if comparator returns true. Required if else is not provided
  4. else (UnitTargetable<T> | ReadonlyArray<UnitTargetable<T>>) — Target unit(s) triggered with data from source if comparator returns false. Required if then is not provided

Returns

  1. (Unit<T>) — The same unit type that passed to source

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: old

Examples

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],
});