In previous blog we have explained what are Interceptors in Angular and gave example of an basic auth interceptor,
In this one we are going to learn how add multiple Interceptors and what are catching Interceptors.
Please have a quick read of the first blog for context,
Now in order to add multiple Interceptors, we first add them in root module file
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
...
@NgModule({
...
imports: [
... ,
HttpClientModule
],
providers: [
... ,
{
provide: HTTP_INTERCEPTORS,
useClass: InterceptorOne,
multi: true,
},
{
provide: HTTP_INTERCEPTORS,
useClass: InterceptorTwo,
multi: true,
}
],
...
})
Note : InterceptorOne and InterceptorTwo are just examples and you have to add your own interceptor class instead of it.
Now we implement our caching Interceptor
This interceptor caches the request only when the headers contains cacheRequest parameter to true.
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs';
import { tap } from 'rxjs/operators';
import { CacheService } from './cache.service';
@Injectable()
export class CachingInterceptor implements HttpInterceptor {
constructor(private readonly cacheService: CacheService) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Don't cache if it's not a GET request
if (req.method !== 'GET') {
return next.handle(req);
}
// delete cache if no header is set by service's method
if (!req.headers.get('cacheRequest')) {
if (this.cacheService.cacheMap.get(req.urlWithParams)) {
this.cacheService.cacheMap.delete(req.urlWithParams);
}
return next.handle(req);
}
// Checked if there is cached data for this URI
const cachedResponse = this.cacheService.getFromCache(req);
if (cachedResponse) {
// In case of parallel requests to same URI,
// return the request already in progress
// otherwise return the last cached data
return (cachedResponse instanceof Observable) ? cachedResponse : of(cachedResponse.clone());
}
// If the request of going through for first time
// then let the request proceed and cache the response
return next.handle(req)
.pipe(tap(event => {
if (event instanceof HttpResponse) {
this.cacheService.addToCache(req, event);
}
}));
}
}
Cache Service : To store and retrieve for caches
import { HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable()
export class CacheService {
cacheMap = new Map<any, any>(null);
getFromCache(req: HttpRequest<any>): HttpResponse<any> | undefined {
const url = req.urlWithParams;
const cached = this.cacheMap.get(url);
if (!cached) {
return undefined;
}
return (this.cacheMap.get(url)).response;
}
addToCache(req: HttpRequest<any>, response: HttpResponse<any>): void {
const url = req.urlWithParams;
const entry = { url, response, addedTime: Date.now() };
this.cacheMap.set(url, entry);
}
}
Sample Get request
getMethod(int param1, cache = false): any {
let headers: HttpHeaders;
if (cache) {
headers = new HttpHeaders({ 'cacheRequest': 'true' });
}
return this.http.get(
'http://apiUrl',
{ headers }
);
}
Top comments (0)