I have a service that makes a call to GET API and receives a response back. I have implemented HTTP Interceptor to properly and globally handle any errors though out the application. I want to do is, when my API returns a particular error, say for example, error 501, I need to retry that request for n no of times and t seconds of delay before every request. I also want to handle a generic error if my retries are over(i.e. if I get error on the last retry, I want to handle it in a particular way). Please help me figure out how to solve this issue.
This is all implemented using Angular 6, solution with correct syntax will be appreciated.
Thank you
You may consider doing this using retryWhen
, delay
, tap
, scan
of RxJS. Something like the following code where an Angular service invokes the Google APIs to authenticate a user in an app that doesn't run on a browser, for e.g. a desktop app. This service uses RxJS to retry the REST API calls at a specific interval in case of failure due to unstable internet connection:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { retryWhen, delay, tap, scan, concatMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class GoogleDeviceAuthService {
private readonly client_id = "<client-id>";
private readonly client_secret = "<client-secret>";
private readonly userCodeRequest = {
"client_id": this.client_id,
"scope": "email profile"
};
private readonly pollGoogleAuthServerRequestTemplate = {
"client_id": this.client_id,
"client_secret": this.client_secret,
"code": "",
"grant_type": "http://oauth.net/grant_type/device/1.0"
}
private readonly userCodeUrl = "https://accounts.google.com/o/oauth2/device/code";
private readonly pollGoogleAuthServerUrl = "https://www.googleapis.com/oauth2/v4/token";
constructor(private readonly http: HttpClient) { }
public getUserCode() {
return this.http.post(this.userCodeUrl, this.userCodeRequest)
.pipe(
retryWhen(err => err.pipe(
scan(
(retryCount, err) => {
if (retryCount > 3)
throw err;
else
return retryCount + 1;
}, 0
),
delay(1000),
tap(err => console.log("Retrying...", err))
)));
}
public checkAuthServerForUserInput(deviceCode) {
let pollGoogleAuthServerRequest = {
...this.pollGoogleAuthServerRequestTemplate,
...{ "code": deviceCode } };
return this.http.post(this.pollGoogleAuthServerUrl, pollGoogleAuthServerRequest)
.pipe(
retryWhen(err => err.pipe(
scan(
(retryCount, err) => {
if (retryCount > 3)
throw err;
else
return retryCount + 1;
}, 0
),
delay(1000),
tap(err => console.log("Retrying...", err))
)));;
}
}