on<ChildEvent> method

System<State, Event> on<ChildEvent>({
  1. ChildEvent? test(
    1. Event event
    )?,
  2. Reduce<State, ChildEvent>? reduce,
  3. void effect(
    1. State state,
    2. ChildEvent event,
    3. Dispatch<Event> dispatch
    )?,
})

Add reduce or effect when event meet some condition.

API Overview

system
  ...
  .on<SomeEvent>(
    test: (Event event) {       
      return event is SomeEvent // test if we are concerned about this event,
        ? event                 // return `SomeEvent` if we are concerned,
        : null;                 // return null if we are not concerned,
    },                          // `test` is nullable, defaults to safe cast as shown.
    reduce: (state, SomeEvent event) => state // compute a new state based
      .copyWith(                              // on current state and event.
        someField: event.someField,           // `reduce` is nullable.
      ), 
    effect: (state, SomeEvent event, dispatch) async { 
      // trigger effect when `SomeEvent` happen.
      // `effect` is nullable.
    },
  )
  ...

Usage Example

Below code showed how to add reduce and effect, when Increment or Decrement event happen.

counterSystem
  ...
  .on<Increment>(
    reduce: (state, event) => state + 1,
    effect: (state, event, dispatch) async {
      await Future<void>.delayed(const Duration(seconds: 3));
      dispatch(Decrement());
    },
  )
  .on<Decrement>(
    reduce: (state, event) => state - 1,
  )
  ...

If Increment happen, it will increase counts by 1, and wait 3 seconds then dispatch a Decrement event to restore counts. If Decrement happen, it will decrease counts by 1.

Implementation

System<State, Event> on<ChildEvent>({
  ChildEvent? Function(Event event)? test,
  Reduce<State, ChildEvent>? reduce,
  void Function(State state, ChildEvent event, Dispatch<Event> dispatch)? effect,
}) {
  final localTest = test ?? safeAs;
  return add(
    reduce: reduce == null ? null : (state, event) {
      return _testEvent(event,
        test: localTest,
        then: (ChildEvent childEvent) => reduce(state, childEvent),
      ) ?? state;
    },
    effect: effect == null ? null : (state, oldState, event, dispatch) {
      if (oldState != null && event != null) {
        _testEvent(event,
          test: localTest,
          then: (ChildEvent childEvent) => effect(state, childEvent, dispatch),
        );
      }
    },
  );
}