0

I have an app, where if an action fails (BiographyUpdate), I'd like to give the user the option to retry the action using a toast. When the user dismisses the toast, it should retry the action if they accept:

@Effect()
  public BiographyUpdate: Observable<any> = this._actions.pipe(
    ofType(AuthActionTypes.BIOGRAPHY_UPDATE),
    map((action: BiographyUpdate) => action.payload),
    switchMap(biography => this._profile.updateBiography(`${Environment.Endpoint}/users/update`, biography)
      .map(() => new BiographyUpdateSuccess())
      .catch(() => Observable.of(new BiographyUpdateFailure(biography)))
    )
  );

  @Effect({ dispatch: false })
  public BiographyUpdateFailure: Observable<any> = this._actions.pipe(
    ofType(AuthActionTypes.BIOGRAPHY_UPDATE_FAILURE),
    map((action: BiographyUpdateFailure) => action.payload),
    tap(payload => {
      const toast = this._toast.create({
        message: "Update failed.",
        ...ToastDefaults,
        duration: 3000,
        closeButtonText: 'Retry'
      });
      toast.onDidDismiss(() => new BiographyUpdate(payload));
      toast.present();
    })
  );

Since the action is called through the UI's callback, I thought this way would work, but the action is never called again. Any suggestions?

EHorodyski
  • 774
  • 1
  • 8
  • 30
  • any error thrown will terminate the stream, see my answer https://stackoverflow.com/questions/53508804/cancel-request-using-redux-observable-is-not-working/53509226#53509226 , this maybe the cause – Fan Cheung Dec 04 '18 at 01:49
  • The effect is called -- if I replace the call to an action with a console log or alert it runs. – EHorodyski Dec 04 '18 at 13:09
  • does it only work on the first time dismiss right? – Fan Cheung Dec 04 '18 at 13:11
  • No, it works all the time -- it just won't invoke the action: `toast.onDidDismiss(() => new BiographyUpdate(payload))` – EHorodyski Dec 04 '18 at 13:13

1 Answers1

0

Figured it out, I needed to dispatch the action. Here is my updated failure action:

For clarity, I'm only dispatching the action if the user closes the Toast, not if it's dismissed automatically. This isn't documented by Ionic, but is possible.

@Effect({ dispatch: false })
  public BiographyUpdateFailure: Observable<any> = this._actions.pipe(
    ofType(AuthActionTypes.BIOGRAPHY_UPDATE_FAILURE),
    map((action: BiographyUpdateFailure) => action.payload),
    tap(payload => {
      const toast = this._toast.create({
        message: "Update failed.",
        ...ToastDefaults,
        duration: 3000,
        closeButtonText: 'Retry'
      });
      toast.onDidDismiss((data, role) => { 
          if (role === 'close') 
              return this._store.dispatch(new BiographyUpdate(payload)); 
      });
      toast.present();
    })
  );
EHorodyski
  • 774
  • 1
  • 8
  • 30