Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attempting to cache HttpClient Request in Angular but seeing unresolved variables

I pretty much copied the code below from the Angular HttpClient Docs

The reason I want to cache HttpClient GETS is because the site makes multiple GET requests to an endpoint but the data only changes once a day. So I'm thinking I could just cache the requests and save some space/time. I do have a browser cache setup on my nginx server, but that doesn't cache client requests, correct?

It's telling me, isCachable, get and put are unresolved. Am I missing an import somewhere or is there something else?

import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpHeaders, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
import {of} from 'rxjs/observable/of';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class RequestCacheManager implements HttpInterceptor {
  constructor(private cache: RequestCache) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    // continue if not cachable.
    if (!isCachable(req)) {
      return next.handle(req);
    }

    const cachedResponse = this.cache.get(req);
    return cachedResponse ?
      of(cachedResponse) : this.sendRequest(req, next, this.cache);
  }

  /**
   * Get server response observable by sending request to `next()`.
   * Will add the response to the cache on the way out.
   */
  sendRequest(req: HttpRequest<any>,
              next: HttpHandler,
              cache: RequestCache): Observable<HttpEvent<any>> {

    // No headers allowed in npm search request
    const noHeaderReq = req.clone({headers: new HttpHeaders()});

    return next.handle(noHeaderReq).pipe(
      tap(event => {
        // There may be other events besides the response.
        if (event instanceof HttpResponse) {
          cache.put(req, event); // Update the cache.
        }
      })
    );
  }
}

I'm hoping to implement this to help cut down on the amount of client side time/requests and space neccasary for my App to function.

like image 382
Zeratas Avatar asked Feb 28 '18 22:02

Zeratas


People also ask

Why is HttpClient return observable?

In general, an observable can return multiple values over time. An observable from HttpClient always emits a single value and then completes, never to emit again. Which is indeed true, Http request/response can't produce any more values once the request completes.

What is the use of HttpClient get () method?

Use the HttpClient.get() method to fetch data from a server. The asynchronous method sends an HTTP request, and returns an Observable that emits the requested data when the response is received. The return type varies based on the observe and responseType values that you pass to the call.

What is the use of HttpClientModule in Angular?

The HttpClientModule is a service module provided by Angular that allows us to perform HTTP requests and easily manipulate those requests and their responses. It is called a service module because it only instantiates services and does not export any components, directives or pipes.

What is observe in HttpClient?

Observe Response HttpClient object allows accessing complete response, including headers. In the browser, response body is a JSON object, which can be copied to a typescript interface or class type. Response headers are key/value pairs. Consider the following code that accesses complete response object.


1 Answers

The documentation at angular.io/guide/http#caching doesn't currently give the full picture.

This blog post is helpful.

You need to implement the RequestCache, called RequestCacheWithMap in the example (and the example also depends on a MessageService).

Then you provide the HttpInterceptor something like this:

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { MyInterceptor } from './http-interceptors/my-interceptor';
import { RequestCacheWithMap } from './services/request-cache.service';
import { MessageService } from './services/message.service';

@NgModule({
  providers: [
    RequestCacheWithMap,
    MessageService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MyInterceptor,
      multi: true,
    },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
like image 179
Derek Hill Avatar answered Oct 18 '22 04:10

Derek Hill