简体   繁体   中英

angular 2 observable resubscribe to reuse data

I am trying to reuse cached data. If there is no cached data then use http to get data. If there is cached data then use the cached data in observable.

here is the data service.ts

import {Injectable} from 'angular2/core';
import {Http, Response, Headers, RequestOptions} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import {Observer} from 'rxjs/Observer';
import 'rxjs/add/operator/share';

import {Hero} from './hero';
//import {HEROES} from './mock-heroes';


@Injectable()
export class HeroService {
  private _baseUrl: string;
  private _cachedHeroes; 

  private _heroesObserver: Observer<Hero[]>;
  private _heroObserver: Observer<Hero>;
  heroes$: Observable<Hero[]>; 
  hero$:   Observable<Hero>; 
  public _dataStore: { heroes: Hero[], hero: Hero };

  constructor (private http: Http) {
        this._dataStore = { heroes: [], hero: {_id: null, name: null} };
        this.heroes$ = new Observable(observer =>  this._heroesObserver = observer).share();
        this.hero$   = new Observable(observer =>  this._heroObserver = observer).share();
        this._baseUrl = 'http://localhost:8081/api/hero/';  // URL to web api
  }

  loadHeroes() {
      if (this._dataStore.heroes.length === 0) {
        this.http.get(`${this._baseUrl}readAll`)
                 .map(response => response.json()).publishReplay(null,1).refCount()
                 .subscribe(data => {
                                     this._dataStore.heroes = data;
                                     this._heroesObserver.next(this._dataStore.heroes);
                                    }, 
                             error => console.log('Could not load heroes.')
                            );
      }
      else {
       //   Observable.of(this._dataStore.heroes)
       this.heroes$.map(data =>this._dataStore.heroes)
       .publishReplay(null,1).refCount()   
       .subscribe(data => {
                                     this._dataStore.heroes = data;
                                     this._heroesObserver.next(this._dataStore.heroes);
                                     console.log(this.heroes$);
                                    }, 
                             error => console.log('Could not load heroes.')
                            );
      //console.log(this._heroesObserver);          
      }
  }
}

The http.get().map().subscribe() is always working. this._heroesObserver.isUnsubscribed always shows false.

But when there is cached data this._heroesObserver.isUnsubscribed always shows true.

The component calls to this function from within ngOnInit()

  ngOnInit() {
    this._heroService.loadHeroes();       
    this.heroes = this._heroService.heroes$;
    this.heroes.subscribe(data => {
                                    data.forEach((h, i) => {
                                        console.log(h); 
                                    });
                                  }, 
                          error => console.log('Could not get hero.')
                         );
  }

Does that matter? I think not. What can I do to make it work?

Updated the code to add .publishReplay(null,1).refCount() .

Now the refCount increments and the isUnsubscribed always shows false. However, the component still cannot get data. The first time when there is no cached data console.log in the component prints all data correctly. But when there is cached data, the console.log prints nothing.

Use publishReplay(1) to change your observable into a hot observable that will remember and replay the last value and supply it to late subscribers:

import * as Rx from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/publishReplay';

this.heroes$ = http.get(...).map(...).publishReplay(1).refCount();

this.heroes$.subscribe(...);

The last replayed value is essentially the cached value, which gets replaced when a new http request is made

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM