Skip to content

Instantly share code, notes, and snippets.

@ganesh-vellanki
Created October 19, 2020 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ganesh-vellanki/136b2bb35a9f7c0f29aa5c4a8485af93 to your computer and use it in GitHub Desktop.
Save ganesh-vellanki/136b2bb35a9f7c0f29aa5c4a8485af93 to your computer and use it in GitHub Desktop.
Caching XHR with angular.
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpHeaders,
HttpResponse
} from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { HttpCacheService } from '../core/services/http-cache.service';
import { tap } from 'rxjs/operators';
import { REQ_CACHE_ALLOW_KEY } from '../constants/constants';
@Injectable()
export class HttpCacheInterceptor implements HttpInterceptor {
constructor(private httpCacheService: HttpCacheService) { }
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
if (!this.isCacheable(request)) {
return next.handle(request);
}
const cachedResponse = this.httpCacheService.get(request);
return cachedResponse ?
of(cachedResponse) : this.sendRequest(request, next, this.httpCacheService);
}
sendRequest(
req: HttpRequest<any>,
next: HttpHandler,
cache: HttpCacheService): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
tap(event => {
// There may be other events besides the response.
if (event instanceof HttpResponse) {
cache.put(req, event); // Update the cache.
}
})
);
}
isCacheable(request: HttpRequest<unknown>) {
return request.headers.get(REQ_CACHE_ALLOW_KEY) === 'true';
}
}
import { Injectable } from '@angular/core';
import { HttpResponse, HttpRequest } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class HttpCacheService {
private maxAgeInMinutes = 10;
constructor() { }
private 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 = (Date.now() - cached.cachedTime) / (1000 * 60) > this.maxAgeInMinutes;
if (isExpired) {
this.cache.delete(url);
return undefined;
}
return cached.response;
}
put(req: HttpRequest<any>, response: HttpResponse<any>): void {
const url = req.urlWithParams;
const entry = { url, response, cachedTime: Date.now() };
this.cache.set(url, entry);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment