import { concat, of, Observable, EMPTY } from 'rxjs'; import { tap } from 'rxjs/operators'; import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpResponse, HttpHandler, HttpEvent } from '@angular/common/http'; import { NaHttpCache } from '../na-http-cache'; @Injectable({ providedIn: 'root' }) export class NaCachingInterceptor implements HttpInterceptor { constructor(private cache: NaHttpCache) { } intercept(req: HttpRequest, next: HttpHandler): Observable> { // Still skip non-GET requests. if (req.method !== 'GET') { return next.handle(req); } // This will be an Observable of the cached value if there is one, // or an empty Observable otherwise. It starts out empty. let maybeCachedResponse: Observable> = EMPTY; // Check the cache. const cachedResponse = this.cache.get(req); if (cachedResponse) { maybeCachedResponse = of(cachedResponse); } // Create an Observable (but don't subscribe) that represents making // the network request and caching the value. const networkResponse = next.handle(req).pipe(tap(event => { // Just like before, check for the HttpResponse event and cache it. if (event instanceof HttpResponse) { this.cache.put(req, event); } })); // Now, combine the two and send the cached response first (if there is // one), and the network response second. return concat(maybeCachedResponse, networkResponse); } }