Created
October 19, 2020 13:52
-
-
Save ganesh-vellanki/136b2bb35a9f7c0f29aa5c4a8485af93 to your computer and use it in GitHub Desktop.
Caching XHR with angular.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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