guard

Method for conditional event routing. It provide a way to control one dataflow with the help of another: when the condition and the data are in different places, then we can use guard with stores as a filters to trigger events when condition state is true, thereby modulate signals without mixing them.

Formulae

guard({ source, filter, target? }): target

When source is triggered check filter for thruthy and call target with data from source if true.

  • If target is not passed, create (Event)(Event.md) with type of source and return it from guard()
  • If filter is (Store)(Store.md) check it value for thruthy
  • If filter is Function call it with data from source and check result for thruthy

guard({source, filter, target?})

Arguments

  1. params (Object): Configuration object

Returns

Event, which fires upon clock is triggered

Example

import { createStore, createEffect, createEvent, guard, sample } from 'effector'
const clickRequest = createEvent()
const fetchRequest = createEffect({
handler: (n) => new Promise((rs) => setTimeout(rs, 2500, n)),
})
const clicks = createStore(0).on(clickRequest, (x) => x + 1)
const requests = createStore(0).on(fetchRequest, (x) => x + 1)
const isIdle = fetchRequest.pending.map((pending) => !pending)
/*
on clickRequest, take current clicks value,
and call fetchRequest with it
if isIdle value is true
*/
guard({
source: sample(clicks, clickRequest),
filter: isIdle,
target: fetchRequest,
})

See ui visualization

Also, guard can accept common function predicate as a filter, to drop events before forwarding them to target

Example 2

import { createEffect, createEvent, guard } from 'effector'
const searchUser = createEffect()
const submitForm = createEvent()
guard({
source: submitForm,
filter: (user) => user.length > 0,
target: searchUser,
})
submitForm('') // nothing happens
submitForm('alice') // ~> searchUser('alice')

Try it

guard(source, {filter: booleanStore})

Arguments

  1. source (Store/Event/Effect): Source unit. Will trigger given guard on updates
  2. filter (Store): Filter store

Example

import { createEvent, createStore, createApi, guard } from 'effector'
const trigger = createEvent()
const $unlocked = createStore(true)
const { lock, unlock } = createApi($unlocked, {
lock: () => false,
unlock: () => true,
})
const target = guard(trigger, {
filter: $unlocked,
})
target.watch(console.log)
trigger('A')
lock()
trigger('B') // nothing happens
unlock()
trigger('C')

Try it

guard(source, {filter: predicate})

Arguments

  1. source (Store/Event/Effect): Source unit. Will trigger given guard on updates
  2. filter ((payload) => Boolean): Predicate function, should be pure

Example 2

import { createEvent, guard } from 'effector'
const source = createEvent()
const target = guard(source, {
filter: (x) => x > 0,
})
target.watch(() => {
console.log('target called')
})
source(0)
// nothing happens
source(1)
// target called

Try it