LiveLoveApp logo

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);

See example on codesandbox

Let's review the example code above:

  1. First, we use the ajax.getJSON() method to create the request and return an Observable.
  2. The catchError() operator will catch an Observable that is emitted with a next notification. In this example, we'll just log the error to the console and rethrow the error.
  3. Then, we use the retryWhen() operator. The operator accepts the notifier Observable that emits each time the source Observable emits an error. Using the mergeMap() operator we return an Observable of null if the notifier has emitted fewer than 2 times and the error's status is 404. Otherwise, we'll return a new Observable using the throwError() operator that immediately emits the error notification.
  4. 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.