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 theerror
to the console and rethrow the error. - Then, we use the
retryWhen()
operator. The operator accepts thenotifier
Observable that emits each time the source Observable emits an error. Using themergeMap()
operator we return an Observable ofnull
if the notifier has emitted fewer than2
times and the error'sstatus
is404
. 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.