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

前端 未结 21 1334
广开言路
广开言路 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:33

    It's .publishReplay(1).refCount(); or .publishLast().refCount(); since Angular Http observables complete after request.

    This simple class caches the result so you can subscribe to .value many times and makes only 1 request. You can also use .reload() to make new request and publish data.

    You can use it like:

    let res = new RestResource(() => this.http.get('inline.bundleo.js'));
    
    res.status.subscribe((loading)=>{
        console.log('STATUS=',loading);
    });
    
    res.value.subscribe((value) => {
      console.log('VALUE=', value);
    });
    

    and the source:

    export class RestResource {
    
      static readonly LOADING: string = 'RestResource_Loading';
      static readonly ERROR: string = 'RestResource_Error';
      static readonly IDLE: string = 'RestResource_Idle';
    
      public value: Observable<any>;
      public status: Observable<string>;
      private loadStatus: Observer<any>;
    
      private reloader: Observable<any>;
      private reloadTrigger: Observer<any>;
    
      constructor(requestObservableFn: () => Observable<any>) {
        this.status = Observable.create((o) => {
          this.loadStatus = o;
        });
    
        this.reloader = Observable.create((o: Observer<any>) => {
          this.reloadTrigger = o;
        });
    
        this.value = this.reloader.startWith(null).switchMap(() => {
          if (this.loadStatus) {
            this.loadStatus.next(RestResource.LOADING);
          }
          return requestObservableFn()
            .map((res) => {
              if (this.loadStatus) {
                this.loadStatus.next(RestResource.IDLE);
              }
              return res;
            }).catch((err)=>{
              if (this.loadStatus) {
                this.loadStatus.next(RestResource.ERROR);
              }
              return Observable.of(null);
            });
        }).publishReplay(1).refCount();
      }
    
      reload() {
        this.reloadTrigger.next(null);
      }
    
    }
    
    0 讨论(0)
  • 2020-11-21 06:36

    according to this article

    It turns out we can easily add caching to the observable by adding publishReplay(1) and refCount.

    so inside if statements just append

    .publishReplay(1)
    .refCount();
    

    to .map(...)

    0 讨论(0)
  • 2020-11-21 06:38

    I assume that @ngx-cache/core could be useful to maintain caching features for the http calls, especially if the HTTP call is made both on browser and server platforms.

    Let's say we have the following method:

    getCustomer() {
      return this.http.get('/someUrl').map(res => res.json());
    }
    

    You can use the Cached decorator of @ngx-cache/core to store the returned value from the method making the HTTP call at the cache storage (the storage can be configurable, please check the implementation at ng-seed/universal) - right on the first execution. The next times the method is invoked (no matter on browser or server platform), the value is retrieved from the cache storage.

    import { Cached } from '@ngx-cache/core';
    
    ...
    
    @Cached('get-customer') // the cache key/identifier
    getCustomer() {
      return this.http.get('/someUrl').map(res => res.json());
    }
    

    There's also the possibility to use caching methods (has, get, set) using the caching API.

    anyclass.ts

    ...
    import { CacheService } from '@ngx-cache/core';
    
    @Injectable()
    export class AnyClass {
      constructor(private readonly cache: CacheService) {
        // note that CacheService is injected into a private property of AnyClass
      }
    
      // will retrieve 'some string value'
      getSomeStringValue(): string {
        if (this.cache.has('some-string'))
          return this.cache.get('some-string');
    
        this.cache.set('some-string', 'some string value');
        return 'some string value';
      }
    }
    

    Here are the list of packages, both for client-side and server-side caching:

    • @ngx-cache/core: cache utility
    • @ngx-cache/platform-browser: SPA/Browser platform implementation
    • @ngx-cache/platform-server: server platform implementation
    • @ngx-cache/fs-storage: storage utility (required for server platform)
    0 讨论(0)
提交回复
热议问题