Search code examples
angularrxjsngrx

NgRx - Selecting AppState in effects


I have an effect in my NgRx application where it needs to dispatch an action as a "side-effect" along with the main final action that the effect should dispatch. But this "side-effect action" depends on a state key that I need to select from the AppState.

I'm afraid that the way I implemented is not correct, since the side effect action is always being dispatched when the AppState key changes. I know that using the NgRx selectors creates a stream of Observables, but I don't know what is the correct implementation to this.

Here is my effect:

createNewTask$ = createEffect(() => this.actions$.pipe(
  ofType(fromAgendaActions.createNewTask),
  concatMap(action => this.agendaService.createNewTask(action.payload)
    .pipe(
      tap(() => {
        this.store.select(selectCurrentDate).subscribe(currentDate => {
          if(moment(action.payload.followUpDate).isBefore(moment().startOf('date'))) {
            this.store.dispatch(fromAgendaActions.getOverdueTasks());
          }
          if(moment(currentDate).startOf('date').isSame(moment(action.payload.followUpDate))) {
            this.store.dispatch(fromAgendaActions.getTasks({ payload: { date: moment(currentDate).format('DD-MM-YYYY') }}));
          }
            });
      }),
      map(() => fromAgendaActions.createNewTaskSuccess()),
      catchError(() => of({ type: fromAgendaActions.AgendaActionsTypes.CreateNewTaskFail, error: 'error' }))
    )
)));

Solution

  • Haven't tried but the following should be ok:

    createNewTask$ = createEffect(() =>
      this.actions$.pipe(
        ofType(fromAgendaActions.createNewTask),
        withLatestFrom(this.store.select(selectCurrentDate)),
        concatMap(([action, currentDate]) =>
          this.agendaService.createNewTask(action.payload).pipe(
            concatMap(() => {
              const actions = [];
              if (
                moment(action.payload.followUpDate).isBefore(
                  moment().startOf('date')
                )
              ) {
                actions.push(fromAgendaActions.getOverdueTasks());
              }
    
              if (
                moment(currentDate)
                  .startOf('date')
                  .isSame(moment(action.payload.followUpDate))
              ) {
                actions.push(
                  fromAgendaActions.getTasks({
                    payload: { date: moment(currentDate).format('DD-MM-YYYY') },
                  })
                );
              }
    
              actions.push(fromAgendaActions.createNewTaskSuccess());
    
              return from(actions).map(a => of(a));
            }),
            catchError(() =>
              of({
                type: fromAgendaActions.AgendaActionsTypes.CreateNewTaskFail,
                error: 'error',
              })
            )
          )
        )
      )
    );