Search code examples
angularngrxngrx-storengrx-effects

NGRX Effects breaks app on error, how to handle errors?


I am using NGRX effects in my app. When it fails it seems to break the stream.

@Effect()
createUser$: Observable<Action> = _action$.ofType(fromUser.CREATE_NEW_USER_ACTION)
  .pipe(
    mergeMap((action: fromUser.CreateNewUserAction) =>
      this._tokenService.post('users', action.payload)
        .pipe(
          map(response => {
            this._router.navigate(
              ["dashboard", "users", "view"],
              { queryParams: { id: response.json().message.id } });
            return new fromUser.CreateNewUserCompleteAction(response.json().message);
          },
            catchError(error =>
              of(new fromUser.CreateNewUserFailedAction(error.json().message))
            )
          )
        )
    )
  );

The error action is never triggered, I tried logging.


Solution

  • What is your tokenService returning? It might be handling any errors from the API call internally. CatchError should work as long as your API call is not burying the error event. If that is the case you may need to throw the error from that service using Observable.throw().

    I typically format my effects more like this for readability.

    @Effect() updateUser$: Observable<Action>;
    
    constructor(action$: Actions, tokenService: TokenService) {
    this.updateUser$ = action$.ofType(fromUser.UPDATE_USER_ACTION)
    .pipe(
        mergeMap((action: fromUser.UpdateUserAction) => 
            tokenService.patch(`users/${this.user.id}`, action.payload)
               .pipe(
                  map(response => {
                     this._router.navigate(
                        ["dashboard", "users", "view"], 
                        { queryParams: { id: response.json().message.id } });
                     return new fromUser.UpdateUserCompleteAction(response.json().message); 
                  },
                  catchError(error => 
                     of(new fromUser.UpdateUserFailedAction(error.json().message))
                  )
               )
            )
        )
    );
    }
    

    This code looks like it should work. Take a look at your TokenService.