Neurism
Neurism

Reputation: 11

Observable error, execute different observable, retry original observable (Angular, RxJs6)

I am working on a project that uses a SSO accross multiple applications. However, the application has it's own separate subscription service. We get the username and the email from the SSO, to create the subscription. If the subscription already exists, we edit it, otherwise we create a new one.

I am trying to write this in an observable pipe to subscribe too.

Basically first try to edit the subscription (we assume it exists), however, if that fails with a certain error (user doesnt exist) - create a brand new subscription, then go back to editing it. If it fails with a different error, like a server error, then just throw that error.

My issue is writing this logic properly. Here is what I have:


    this.userSubscriptionService.getSubscriptions(this.userName).pipe(
      catchError((err) => {
        if (err.error.message === 'Enter a valid username') {
          return this.userSubscriptionService.createSubscription(this.userName, this.emailAddress);
        } else {
          return throwError(err);
        }
      }),
      flatMap((userSubs: IUserSubscriptions) => this.editSubscription(userSubs))
    ).subscribe();

First I get the subscription, so I can edit it with the new information. However, if getSubscription throws an error, I want to then create the subscription using the username and email obtained from a separate SSO service, and then edit the brand new subscription to include the new information.

createSubscription will only return a boolean based on if it worked, whereas getSubscription returns all the information I need.

I am having trouble figuring out how to write the retry logic after I catch the error.

Please let me know if you need info..

Thank you for any feedback.

========================== Edit =======================

So ultimately what I am trying to solve, is if the user doesn't exist, create the user, then restart the whole pipe. And I came up with this


    this.userSubscriptionService.getSubscriptions(this.userName).pipe(
      catchError((err) => {
        if (err.error.message === 'Enter a valid username') {
          return this.userSubscriptionService.createSubscription(this.userName, this.emailAddress);
        } else {
          return throwError(err);
        }
      }),
      flatMap((userSubs: IUserSubscriptions) => this.editSubscription(userSubs)),
      retryWhen(err => {
        return err;
      }),
    ).subscribe();

Which works - unless the backend is down or there is some other reoccuring error. If the error can't be resolved, it will retry my pipe infinitely.

Upvotes: 0

Views: 63

Answers (1)

Neurism
Neurism

Reputation: 11

Here is the answer I came up with. So far I haven't been able to break and it does not seem like terribly bad practice. However, I would not be surprised if there was a better solution, or a more proper syntax. Please advise.

this.userSubscriptionService.getSubscriptions(this.userName).pipe(
  catchError((err) => {
    if (err.error.message === 'Enter a valid username') {
      return this.userSubscriptionService.createSubscription(this.userName, this.emailAddress);
    } else {
      return throwError(err);
    }
  }),
  flatMap((userSubs: IUserSubscriptions) => this.editSubscription(userSubs)),
  retry(1),
).subscribe();

Upvotes: 1

Related Questions