0

I've a post request that i'm using inside my angular application. My goal is to check the message inside the error, and according to that retry the request BUT i'd like to retry a certain amount of attempts.

In the beginning i was trying this approach:

public post(url, data) {
    this._http.post(url, data).pipe(
      retry(3),
      catchError((err: HttpErrorResponse) => {
        if (err.message === 'something') {
          return EMPTY;
        }
      }),
    )
  } 

But in this case it was retrying to send the failing req without checking the condition inside catchError.
So i was thinking to use the retryWhen() operator, but here i don't know how to specify the amount of attempts that should be executed

Anna
  • 131
  • 2
  • 11
  • 2
    Does this answer your question? [How to create an RXjs RetryWhen with delay and limit on tries](https://stackoverflow.com/questions/44911251/how-to-create-an-rxjs-retrywhen-with-delay-and-limit-on-tries) – superhawk610 Jun 11 '21 at 17:17

1 Answers1

0

Using RetryWhen

This isn't really idiomatic RxJS, but I think it's a bit easier to understand this first and then jump into better stream manipulation later.

retryWhen gives you a stream of errors that are emitted as values. You can do anything with that as you wish, including ignoring it. This this case, I use defer to create some local state (a counter) and then subscribe to those errors in order to count specific errors.

new Observable(observer => {
  observer.next(1);
  observer.error({message: "something"});
  return {unsubscribe: () => {/* Do Nothing*/}};
}).pipe(
  retryWhen(errors => defer(() => {
    let count = 0; // Some state, created just once
    return errors.pipe(
      switchMap(err => {
        // You effectively have 3 options here. return:
        //  1: of(any) -> retry the source Observable
        //  2: throwError(any) -> source Observable throws this error
        //  3: EMPTY -> source Observable completes
        if (err.message === "something" && count < 3){
          count++;
          return of(null);
        }
        return throwError(err);
      })
    )
  }))
).subscribe({
  next: v => console.log("Next: ", v),
  error: e => console.log("Error: ", e),
  complete: () => console.log("Complete")
});

This should run with the following output (Comments are mine ;) ):

Next: 1  // Emission before error
Next: 1  // Emission from first retry
Next: 1  // Emission from second retry
Next: 1  // Emission from third retry
Error: {"message":"something"} // Too many errors, not retrying any more
Mrk Sef
  • 7,557
  • 1
  • 9
  • 21