Search code examples
angulartoastngrx

Where in the redux lifecycle I should call methods to show notifications (toasts)?


I am building angular2 app with ngrx/store. Where in the redux lifecycle I should call methods to show notifications (toasts)?

My current guess is that I should do it in side effects (I use ngrx/effects).

@Effect({ dispatch: false }) public newBidPublished$: any = this._actions$
    .ofType(BiddingStatusActions.NEW_BID_PUBLISHED)
    .map((action) => action.payload)
    .map((biddingStatus: GetBiddingStatusApiResponseModel) => {
        let msg = '<p>New bid has arrived.</p>';

        // PROBLEM HERE: I don't have access to previous bidding status here:
        if (biddingStatus.tenderRank !== 1 && previousBiddingStatus.tenderRank === 1) {
            msg += '<p>You are no longer in leading position.</p>';
        }

        this._notificationsService.info(msg);
    });

However there is one big problem: I need to access previous state to be able to compare if current bid has lost leading position. The only place where I am able to access both current and previous state is reducer. But I doubt it is a good place to show notifications and as it is not a service, I cannot inject NotificationService there.


Solution

  • I would use an example from my own application. The main point is to use the selector which will select for you the current state before you modify it (before the moving new data from Effect to Reducer).

    @Effect()
    logout$: Observable<RouterActions.All | AccountActions.All> = this.actions$
    .ofType<AccountActions.Logout>(AccountActions.LOGOUT)
    .pipe(
      exhaustMap(() => this.API.auth.revokeToken()),
      // We are using selector to get a slice of the state
      withLatestFrom(this.store.select(fromAccount.selectUser)),
      // The operator above returns an array and we select the second item
      // which is our user/your state.
      map(([, user]) => user),
      map((user: User) => this.redirectUser(user))
    );