24 Jul 2024
5 min

retryWhen – RxJS Reference

retryWhen

Just as a plain observable retryWhen passes values along to the observer (mirroring) until an error in the source stream occurs. When that happens, the operator executes a callback function passing in the stream that will be emitting the errors starting with the current one that has just occurred. Regardless of the number of errors and retries, the callback function is only executed once.

The function is expected to return an observable that will be used as a guide to notify the operator when to retry the subscription to the original source observable. The operator subscribes to the returned guiding observable only once and doesn’t unsubscribe on future errors or until the original source observable completes. If that guiding observable calls complete or error then the retryWhen will send complete or error notification to the observer. Any other value emitted from the guiding observable will cause the operator to resubscribe to the original source observer.

retryWhen operator works in the following way:

  1. Subscribe to a source observable
  2. When a new value arrives from a source observable, send the value to the observer
  3. If the source observable throws an error, execute a callback function and subscribe to the returned guiding observable
  4. When a new value arrives from the guiding observable, re-subscribe to the original source
  5. If the guiding observable completes or throws an error, send the complete or error notification to the observer
  6. Once the source observable completes, send the complete notification to the observer

Usage

Errors in programs happen all the time and RxJS is no exception. For example, a network request can fail because of numerous reasons. It’s always useful to have a mechanism to retry an action.

For simple retries of network requests the retry operator is preferred. But when you need to retry based on some criteria, for example, an error description, you need to use retryWhen.

Here’s an example of using retryWhen to retry the request using information about the error:

const url = 'https://i.imgur.com/fHyEMsl.jpg';

fromFetch(url).pipe(
   switchMap((response) => response.json()),
   retryWhen((errors) => {
           return errors.pipe(
               takeWhile((error) => {
                   if (error instanceof SyntaxError) {
                       throw new Error(error.message);
                   }

                   return true;
               })
           );
       }
   )
).subscribe();

Playground

Additional resources

See also

Share this post

Sign up for our newsletter

Stay up-to-date with the trends and be a part of a thriving community.