Angular RxJS retry

By Arvind Rai, January 25, 2024
This page will walk through Angular RxJS retry operator example. retry operator returns source Observable with the exception of an error. When source Observable calls error then retry operator resubscribe it for the maximum of given number of time. If Observable starts emitting elements and suppose at any point it calls error before completion, then retry operator will resubscribe the source Observable and starts emitting from start again. Suppose we have used retry(3) in our code, it means for any error in source Observable, it will be resubscribed up to 3 times. If in first attempt of resubscribe by retry(3), it completes normally then no other attempt to resubscribe will be made.
RxJS retry operator is imported as following.
import { retry } from 'rxjs/operators'; 
Here on this page we will discuss retry operator with examples step by step.

1. Understanding RxJS retry

The RxJS retry operator subscribes the source Observable if it does not complete due to error. Now find the examples for the given scenarios.
Ex.1: Total max 3 retry, but no success and throw error.
For the demo suppose we have of(1,2,3,4) that will return Observable instance and on subscribe it will emit 1,2,3,4. For the retry demo we will throw error so that this Observable instance does not complete successfully.
of(1,2,3,4).pipe(
  mergeMap(data => {
    if (data === 3) {
	return throwError('Error Occurred.');
    }
    return of(data);
  }),
  retry(3)
).subscribe(res => console.log(res),
   err => {
     console.log("Retried for 3 times.");
     console.error(err);
   }
); 
Output
1,2,1,2,1,2,1,2
Retried for 3 times.
Error occurred. 
Look into the above code. When the data is 3, an error is thrown. But before throwing error on subscribe, retry will try for 3 times maximum to get subscribe it successfully. If no success then finally error will be thrown. The Observable instance will be subscribed 1+ 3 times totally. If in first retry only, source Observable is subscribed with no error, then there will be no more retry.

Ex.2 : Total max 5 retry, but success in 3rd retry
let retryCount = 0;
of('a','b','c','d').pipe(
	mergeMap(data => {
	  if (data === 'c' && retryCount !== 3) {
		retryCount= retryCount + 1;
		return throwError('Error Occurred.');
	  }
	  return of(data);
	}),
	retry(5)
).subscribe(res => console.log(res),
	err => {
	   console.log("Number of retry: "+ retryCount);
	   console.error(err);
	},
	() => console.log("Processing Complete. Number of retry: "+ retryCount)
); 
Output
a b a b a b a b c d
Processing Complete. Number of retry: 3 

In the above code for the first subscribe and retry 1 subscribe and retry 2 subscribe, there are errors. But in third retry, error is not thrown and Observable successfully subscribed and completed.

2. retry and catchError

Here we will create an example of retry with catchError operator. catchError handles the errors thrown by source Observable. Using catchError we can throw a default value or user defined error.
of("A", "B").pipe(
  switchMap(el => {
	if (el === "B") {
	  throw new Error("Error occurred.");
	}
	return el;
  }),
  retry(2),
  catchError(err => {
	console.error(err.message);
	console.log("Error is handled");
	return of("X"); //return defualt value as X
  })
).subscribe(el => console.log(el),
	err => console.error(err),
	() => console.log("Processing Complete.")
); 
Output
A A A
Error occurred.
Error is handled
X 
In the above code we are throwing error when Observable emits "B". We have passed retry count 2. After all retry, we are still throwing error in our code. Once all the retry is complete then error is caught by catchError operator. From catchError we are throwing source Observable with default element as "X".

3. retry with HttpClient

When we access data over HTTP, some errors can be handled by just retrying request such as if errors are transient and unlikely to repeat. For example if we have slow network error and our request could not become successful then there are the chances to make request successful if request is retried. Find the sample example.
getBook(id: number): Observable<Book> {
  let url = this.bookUrl + "/" + id;   

  return this.http.get<Book>(url).pipe(
	tap(() => console.log(url)),
	retry(3),  // retry the failed request up to 3 times
	catchError(err => {
		console.log(err);
		return of(null);
	})
  );
} 

4. Output

Download the source code and run the application. We can see output in console as following.
Angular RxJS retry

5. Reference

RxJS retry

6. Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us