redux-observable wont be execute after catchError

Viewed 1551

I am using redux-observable in my angular project. I have an updateNode function in my epics with catchError handling. I dispatch action DB_UPDATE_NODE many times and everything work well. However the time action execute catchError when I dispatch that action again, updateNode function wont be called any more.

public updateNode(action$: Observable<IScenarioNodesAction>, store: Store<IAppState>) {
  return action$.pipe(
    ofType(ScenarioNodeActionType.DB_UPDATE_NODE),
    flatMap((action) => {
     return  this._scenarioNodeService.update(action.payload.botId);
    }),
    flatMap(data => [
      this._scenarioNodeAction.updateNode(data),
    ]),
    catchError((error) => { 
      return Observable.of(this._commonAction.showError(error));
    })
  );
}
2 Answers

You have to catch the error on the service's stream.

flatMap((action) => {
  return this._scenarioNodeService.update(action.payload.botId)
             .pipe(catchError(...)) ;
})

See the docs for more information.

Here we placed the catchError() inside our mergeMap(), but after our AJAX call; this is important because if we let the error reach the action$.pipe(), it will terminate it and no longer listen for new actions.

If your observable returns an errors it stops the observer from getting new events.

Please add to catchError something like:

  public updateNode(action$: Observable<IScenarioNodesAction>, store: Store<IAppState>){
    return action$.pipe(
      ofType(ScenarioNodeActionType.DB_UPDATE_NODE),
      flatMap((action) => {
       return  this._scenarioNodeService.update(action.payload.botId);
      }),
        flatMap(data => [
          this._scenarioNodeAction.updateNode(data),
        ]) ,
        catchError((error) => { 
              retryWhen((errors) => {
               return errors
                .pipe(delay(1000), take(1))
                .concat(Observable.throw(`Error`));
            },
        ),
      })
    );

  } 

What the above does it waits a second delay(1000) and retries an amount of times take(1). If the error persists it throws error .concat(Observable.throw('Error')). In your case you just call showError and drop the connection.

Related