Caching HTTP Requests with Angular
Posted By : Deepak Rawat | 30-Nov-2018
When we are working with Angular application, we often make
In this
Requirement:
- Angular 5.1+
In an angular
After setting up the HTTP interceptors, all of our HTTP requests will go through this, and then we can do the caching. Let’s take a
So for
import { Injectable } from '@angular/core'; import { HttpEvent, HttpRequest, HttpResponse, HttpInterceptor, HttpHandler } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import { startWith, tap } from 'rxjs/operators'; import 'rxjs/add/observable/of'; import { RequestCache } from './request-cache.service'; @Injectable() export class CachingInterceptor implements HttpInterceptor { constructor(private cache: RequestCache) {} intercept(req: HttpRequest<any>, next: HttpHandler) { const cachedResponse = this.cache.get(req); return cachedResponse ? Observable.of(cachedResponse) : this.sendRequest(req, next, this.cache); } sendRequest( req: HttpRequest<any>, next: HttpHandler, cache: RequestCache): Observable<HttpEvent<any>> { return next.handle(req).pipe( tap(event => { if (event instanceof HttpResponse) { cache.put(req, event); } }) ); } }
To create an interceptor we have to implement the
Now let see the RequestCache service.
import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse } from '@angular/common/http';
const maxAge = 30000;
@Injectable()
export class RequestCache {
cache = new Map();
get(req: HttpRequest<any>): HttpResponse<any> | undefined {
const url = req.urlWithParams;
const cached = this.cache.get(url);
if (!cached) {
return undefined;
}
const isExpired = cached.lastRead < (Date.now() - maxAge);
const expired = isExpired ? 'expired ' : '';
return cached.response;
}
put(req: HttpRequest<any>, response: HttpResponse<any>): void {
const url = req.url;
const cacheEntry = { url, response, lastRead: Date.now() };
this.cache.set(url, cacheEntry);
const expired = Date.now() - maxAge;
this.cache.forEach(expiredEntry => {
if (expiredEntry.lastRead < expired) {
this.cache.delete(expiredEntry.url);
}
});
}
}
The RequestCache service implements a get and put method, and it works with a map. Note here we are also removing the old cache map, so that stale data should not be there in the cache.
Now our next step is to enable the HTTP interceptor, for this let’s look at the app.module.ts file.
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { RequestCache } from './request-cache.service'; import { CachingInterceptor } from './caching-interceptor.service'; // ... providers: [ RequestCache, { provide: HTTP_INTERCEPTORS, useClass: CachingInterceptor, multi: true } ], // ...
Now you can see the ApiService is only responsible for the request and not for caching the response. For caching we are using the separate service file, and with the help of HTTP
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Deepak Rawat
Deepak is a Web and Mobile application Sr. Lead Frontend developer and good working experience with JQuery , AngularJS , Javascript and PhoneGap. His hobbies are listening to music and photography.