Angular 2, Concurrency in a shared service http observable

I have a shared service (starting from this suggestion) that cache and returns some data after first http request:

export class SharedService {
  constructor(private http:Http) {
  }

  getData() {
    if (this.cachedData) {
      return Observable.of(this.cachedData);
    } else {
      return this.http.get(...)
            .map(res => res.json())
            .do((data) => {
              this.cachedData = data;
            });
    }
  }
}

My problem is that I have some directives and components inside the same template that are all initialized at the same time and each one call simultaneously (inside ngInit function) the getData method (all of them before the first one succeeded) and so the service starts many http requests instead of returning cached data.
Can someone suggest me how to avoid this side effect?

2
Leave a Reply

avatar
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

Your solution doesn’t cover all cases. Compare it to my approach from https://stackoverflow.com/a/36291681/217408 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 { // create the request, store the `Observable` for subsequent subscribers this.observable = this.http.get('/someUrl') .map(res => res.json()) .do(val => { this.data = val; // when the cached data is available we don't need the `Observable` reference anymore this.observable = null; }) // make it shared… Read more »

Jason
Guest

You have to declare your service in the bootstrap method:

bootstrap(AppComponent, [SharedService]);

The service will be instanciated only once (singleton) so it should resolve your problem.