RetryWhen Operator
retryWhen() Operator
The retryWhen() operator provides a mechanism for conditionally retrying a source Observable that emits an error notification.
When the source Observable emits an error notification the retryWhen() operator invokes the notifer function provided.
The notifier function receives an errors Observable.
When the errors Observable emits either an error or complete notification then the operator will invoke the error() or complete() method on the child subscription.
If next notification is emitted from the errors Observable then the operator resubscribes to the source Observable.
Example
The explanation for the retryWhen() operator is complex.
So, let's try to comprehend the operator using an example.
In this example we are going intentionally request a user from the API that does not exist.
When an error occurs due to the 404 response from our API we'll use the retryWhen() operator to retry the request two additional times.
import { of, throwError } from "rxjs";
import { ajax } from "rxjs/ajax";
import { catchError, mergeMap, retryWhen } from "rxjs/operators";
const source = ajax.getJSON(`https://reqres.in/api/users/20`).pipe(
  catchError((error) => {
    console.error("catchError", error);
    return throwError(error);
  }),
  retryWhen((notifier) =>
    notifier.pipe(
      mergeMap((error, index) => {
        if (index < 2 && error.status === 404) {
          return of(null);
        }
        return throwError(error);
      })
    )
  )
);
window.setTimeout(() => {
  source.subscribe({
    error: (e) => console.error("observer", e),
    next: console.log,
    complete: () => console.log("complete")
  });
}, 2000);
Let's review the example code above:
- First, we use the 
ajax.getJSON()method to create the request and return an Observable. - The 
catchError()operator will catch an Observable that is emitted with a next notification. In this example, we'll just log theerrorto the console and rethrow the error. - Then, we use the 
retryWhen()operator. The operator accepts thenotifierObservable that emits each time the source Observable emits an error. Using themergeMap()operator we return an Observable ofnullif the notifier has emitted fewer than2times and the error'sstatusis404. Otherwise, we'll return a new Observable using thethrowError()operator that immediately emits the error notification. - To make it a little easier to see the failed requests in the developer tools I've set a timeout to 2000 milliseconds before subscribing.