如何缓存api调用的响应?

时间:2019-07-18 19:13:48

标签: angular angular-http-interceptors

我想缓存不同城市的api调用。在bankhttp.service.ts

中提到了api。

my-interceptor.service.ts中包含的拦截器和reqCache.service.ts中的拦截器用于缓存呼叫。

home.component.ts用于处理包含城市为孟买的api。

在app.module.ts的providers数组中包含以下代码

缓存api调用的正确过程是什么,这样就不会一次又一次地请求相同的端点         提供者:[BankhttpService,         RequestCache,          {提供:HTTP_INTERCEPTORS,useClass:CachingInterceptor,多:            真实}          ]

  </my-interceptor.service.ts
   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 './requestCache.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);
    }
   })
  );
  }
  }
   />


   </requestCache.service.ts
    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 entry = { url, response, lastRead: Date.now() };
    this.cache.set(url, entry);

    const expired = Date.now() - maxAge;
    this.cache.forEach(expiredEntry => {
      if (expiredEntry.lastRead < expired) {
        this.cache.delete(expiredEntry.url);
      }
     });
     }
    }  
    />


   </bankhttp.service.ts
   import { Injectable } from '@angular/core';
   import { HttpClient, HttpHeaders, HttpClientModule } from 
   '@angular/common/http';
   import { HttpErrorResponse, HttpParams } from '@angular/common/http';

   import { Observable } from 'rxjs/Observable'
   import 'rxjs/add/operator/catch';
   import 'rxjs/add/operator/do';


  @Injectable({
  providedIn: 'root'
   })

  export class BankhttpService {

  public a1 = [];
  private baseUrl = "https://vast-shore-74260.herokuapp.com/banks";
  public city1 = "BANGALORE"
  public city2 = "MUMBAI"
  public city3 = "DELHI"
  public city4 = "CHENNAI"
  public city5 = "HYDERABAD"



 constructor(private _http: HttpClient) {
  console.log('Bank http service called');
 }

 private handleError(err: HttpErrorResponse) {
   console.log('Handle http error');
   console.log(err.message);
   return Observable.throw(err.message);
  }

  public getBangaloreBranches(): Observable<any> {

   let myResponse = this._http.get(this.baseUrl + '?city=' + this.city1);
    //console.log(myResponse);
   return myResponse;
  }

  public getMumbaiBranches(): Observable<any> {

  let myResponse = this._http.get(this.baseUrl + '?city=' + this.city2);
  //console.log(myResponse);
   return myResponse;
  }


   public getDelhiBranches(): Observable<any> {

    let myResponse = this._http.get(this.baseUrl + '?city=' + this.city3);
     //console.log(myResponse);
    return myResponse;
   }

   public getChennaiBranches(): Observable<any> {

    let myResponse = this._http.get(this.baseUrl + '?city=' + this.city4);
     //console.log(myResponse);
    return myResponse;
    }

   public getHyderabadBranches(): Observable<any> {

   let myResponse = this._http.get(this.baseUrl + '?city=' + this.city5);
   //console.log(myResponse);
   return myResponse;
   }
   }
   />



   <home.component.ts
    import { Component, OnInit, Inject, ViewChild, ElementRef } from 
     '@angular/core';
    /*importing mat-table components*/
      import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from 
     '@angular/material/dialog';
      import { MatSort, MatTableDataSource, MatPaginator, 
      MatCheckboxModule } from '@angular/material';
     /*importing services*/
     import { BankhttpService } from '../bankhttp.service';
      /*importing selection model to provide checkboxes to the list of 
     banks*/
     import { SelectionModel } from '@angular/cdk/collections';


     /*interface for the json data present in the api*/
     export interface User {
      ifsc: string;
      bank_id: string;
      branch: string;
      address: string;
      city: string,
      district: string,
      state: string,
      bank_name: string
      }

     @Component({
     selector: 'app-home',
     templateUrl: './home.component.html',
     styleUrls: ['./home.component.css'],
     styles: [
     `
       table {
         width: 100%;
       }


       th.mat-sort-header-sorted {
         color: black;
       }

      `
       ]
      })
      export class HomeComponent implements OnInit {
      public value = [];
      selectedRowIndex: any;
      displayedColumns: string[] = ['favorite', 'bank_name', 'ifsc', 
      'bank_id', 'branch', 'city', 'district', 'state'];
       dataSource;
       user;
       data
       users: User[];


       selection = new SelectionModel<User>(true, []);

       @ViewChild('button') button: ElementRef;

       @ViewChild(MatPaginator) paginator: MatPaginator;

       @ViewChild(MatSort) sort: MatSort;

     /** Whether the number of selected elements matches the total number 
    of rows. */
     isAllSelected() {
           const numSelected = this.selection.selected.length;
           const numRows = this.dataSource.length;
           return numSelected === numRows;
       }

      /** Selects all rows if they are not all selected; otherwise clear 
      selection. */
      masterToggle() {
      this.isAllSelected() ?
      this.selection.clear() :
      this.dataSource.forEach(row => this.selection.select(row));
       }

      /** The label for the checkbox on the passed row */
      checkboxLabel(row?: User): string {
       if (!row) {
         return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
        }
       return `${this.selection.isSelected(row) ? 'deselect' : 'select'} 
        row ${row.ifsc + 1}`;
      }


     constructor(public bankHttpService: BankhttpService, public dialog: 
      MatDialog) {
     console.log('Home component constructor is called');


     if (localStorage.getItem('fav') === '' || localStorage.getItem('fav') 
       === null) {

     }     else {
           this.value = JSON.parse(localStorage.getItem('fav'));
           console.log('from localStorage', this.value)
     }

     }

      ngOnInit() {
      console.log('Home component onIniti called');
      /*subscribing to the services*/
      this.bankHttpService.getMumbaiBranches()
      .subscribe((users: User[]) => {

       this.users = users;

       this.dataSource = new MatTableDataSource(users);

       this.dataSource.paginator = this.paginator;

        this.dataSource.sort = this.sort;

       });
      }

     /*filter the list of banks*/
     applyFilter(filterValue: string) {
     filterValue = filterValue.trim(); // Remove whitespace
     filterValue = filterValue.toLowerCase(); // Datasource defaults to 
      lowercase matches
      this.dataSource.filter = filterValue;
      }

    toggle = true;
    status = 'Enable';
    selectedUser: any;

  /*function triggered when click event is performed on the checkboxes 
    adjacent to the bank list*/
        activeSkill(element: any) {
       let checkExists: boolean = false;
       console.log(this.value)
       console.log(this.value.length)
       console.log(element.ifsc)
       for (let i = 0; i < this.value.length; i++) {
       if (element.ifsc === this.value[i].ifsc) {
        checkExists = true;
        console.log(checkExists)
      }
    }
   if (checkExists === false) {
    console.log(checkExists)
    this.value.push(element);
   }
   /*storing the data selected during click event inside the local storage 
    of 
   the browser*/
   localStorage.setItem('fav', JSON.stringify(this.value));
   }
   }

   />

0 个答案:

没有答案