What is the correct way to share the result of an Angular Http network call in RxJs 5?

前端 未结 21 1286
广开言路
广开言路 2020-11-21 06:11

By using Http, we call a method that does a network call and returns an http observable:

getCustomer() {
    return          


        
21条回答
  •  悲&欢浪女
    2020-11-21 06:23

    Cache the data and if available cached, return this otherwise make the HTTP request.

    import {Injectable} from '@angular/core';
    import {Http, Headers} from '@angular/http';
    import {Observable} from 'rxjs/Observable';
    import 'rxjs/add/observable/of'; //proper way to import the 'of' operator
    import 'rxjs/add/operator/share';
    import 'rxjs/add/operator/map';
    import {Data} from './data';
    
    @Injectable()
    export class DataService {
      private url: string = 'https://cors-test.appspot.com/test';
    
      private data: Data;
      private observable: Observable;
    
      constructor(private http: Http) {}
    
      getData() {
        if(this.data) {
          // if `data` is available just return it as `Observable`
          return Observable.of(this.data); 
        } else if(this.observable) {
          // if `this.observable` is set then the request is in progress
          // return the `Observable` for the ongoing request
          return this.observable;
        } else {
          // example header (not necessary)
          let headers = new Headers();
          headers.append('Content-Type', 'application/json');
          // create the request, store the `Observable` for subsequent subscribers
          this.observable = this.http.get(this.url, {
            headers: headers
          })
          .map(response =>  {
            // when the cached data is available we don't need the `Observable` reference anymore
            this.observable = null;
    
            if(response.status == 400) {
              return "FAILURE";
            } else if(response.status == 200) {
              this.data = new Data(response.json());
              return this.data;
            }
            // make it shared so more than one subscriber can get the result
          })
          .share();
          return this.observable;
        }
      }
    }
    

    Plunker example

    This article https://blog.thoughtram.io/angular/2018/03/05/advanced-caching-with-rxjs.html is a great explanation how to cache with shareReplay.

提交回复
热议问题