onRun method

System<State, Event> onRun({
  1. required Disposer? effect(
    1. State initialState,
    2. Dispatch<Event> dispatch
    ),
})

Add effect on system run.

This operator will inject effect when system run, For example, We can trigger networking call by dispatch a trigger event:

 ...
 .on<LoadData>(effect: (state, event, dispatch) async {
   try {
     final data = await api.call(state.itemId);
     dispatch(LoadDataSuccess(data));
   } on Exception {
     dispatch(LoadDataError());
   }
 })
 .onRun(effect: (initialState, dispatch) {
    dispatch(LoadData()); 
 },);

effect can return an optional Disposer. This can be used when this system has interaction with other service, which has listenable API like Stream, ChangeNotifier or System. With these cases, we can listen to them (Stream) when system run, return Disposer contains cancel logic. Then Disposer will be called, when system disposer get called.

 ...
 .onRun(effect: (initialState, dispatch) {
   final timer = Stream
     .periodic(const Duration(seconds: 1), (it) => it);
   final subscription = timer.listen((it) => dispatch('$it'));
   return Disposer(() => subscription.cancel());
 },);

Implementation

System<State, Event> onRun({
  required Disposer? Function(State initialState, Dispatch<Event> dispatch) effect,
}) => withContext<_OnRunContext>(
  createContext: () => _OnRunContext(),
  effect: (context, state, oldState, event, dispatch) {
    if (event == null) {
      context.disposer = effect(state, dispatch);
    }
  },
  dispose: (context) {
    if (context.disposer != null) {
      context.disposer?.call();
      context.disposer = null;
    }
  }
);