Reputation: 423
I have Multiple API in a single component, where on token expire interceptor runs multiple times, for example, if I have 4 GET API in a single component then 4 times interceptor will run on token expire
Below is the code for interceptor
my.httpInterceptor.ts
import {
Injectable
} from "@angular/core";
import {
tap
} from "rxjs/operators";
import {
ToastyService,
ToastOptions
} from 'ng2-toasty';
import {
Router
} from "@angular/router";
import {
_throw
} from 'rxjs/observable/throw';
import 'rxjs/add/operator/do';
import 'rxjs/Observable';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpResponse,
HttpErrorResponse,
HttpHeaders
} from "@angular/common/http";
import {
Observable
} from "rxjs/Observable";
@Injectable()
export class MyInterceptor implements HttpInterceptor {
constructor(private router: Router, private toastyService: ToastyService, ) {}
//function which will be called for all http calls
intercept(
request: HttpRequest < any > ,
next: HttpHandler
): Observable < HttpEvent < any >> {
//how to update the request Parameters
if (JSON.parse(localStorage.getItem('userDetails'))) {
let authToken = JSON.parse(localStorage.getItem('userDetails'));
if (authToken.currentUserToken != null) {
const authReq = request.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer' + authToken.currentUserToken
})
});
return next.handle(authReq)
.catch((err) => {
if (err) {
let errorCodes = [404, 500, 422, 412, 424, 409];
if (errorCodes.includes(err.status)) {
let toastOptions: ToastOptions = {
title: "Error",
msg: "Error",
showClose: true,
timeout: 5000,
theme: 'default'
};
toastOptions.msg = err.error.errors.name;
this.toastyService.error(toastOptions);
}
if (err.status === 401) {
this.router.navigate(['/']).then((nav) => {
// debugger;
if (nav) {
if (this.router.url === '/') {
setTimeout(() => {
let toastOptions: ToastOptions = {
title: "Session Expired",
msg: "Please login again to access",
showClose: true,
timeout: 5000,
theme: 'default',
}
// toastOptions.msg = "Session Expired";
this.toastyService.error(toastOptions);
});
}
}
});
}
return _throw(err.message);
}
});
}
} else {
const updatedRequest = request.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
});
return next.handle(updatedRequest)
}
}
}
How to avoid calling interceptor multiple times.
Upvotes: 3
Views: 3576
Reputation: 178
Interceptors are invoked for all outgoing http requests. However, you can filter the request URLs you want to apply your logic:
@Injectable()
export class MyInterceptor implements HttpInterceptor {
constructor(private router: Router, private toastyService: ToastyService) {
}
//The API you want to intercept its requests (you could take it from a global constants file)
API_URL = "http://www.example.com/host/to/intercept";
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
//only get the token from localStorage when the request points to the API that needs authorization
if (request.url === this.API_URL) {
let userDetails = localStorage.getItem('userDetails');
if (userDetails != null) {
let authToken = JSON.parse(userDetails);
if (authToken.currentUserToken != null) {
const authReq = request.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Bearer' + authToken.currentUserToken
})
});
return next.handle(authReq)
.catch((err) => {
if (err) {
let errorCodes = [404, 500, 422, 412, 424, 409];
if (errorCodes.includes(err.status)) {
let toastOptions: ToastOptions = {
title: "Error",
msg: "Error",
showClose: true,
timeout: 5000,
theme: 'default'
};
toastOptions.msg = err.error.errors.name;
this.toastyService.error(toastOptions);
}
if (err.status === 401) {
this.router.navigate(['/']).then((nav) => {
// debugger;
if (nav) {
if (this.router.url === '/') {
setTimeout(() => {
let toastOptions: ToastOptions = {
title: "Session Expired",
msg: "Please login again to access",
showClose: true,
timeout: 5000,
theme: 'default',
}
// toastOptions.msg = "Session Expired";
this.toastyService.error(toastOptions);
});
}
}
});
}
return _throw(err.message);
}
});
}
} else {
const updatedRequest = request.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
});
return next.handle(updatedRequest);
}
}
}
}
Upvotes: 1