David Elsner David Elsner - 11 days ago 5
Javascript Question

Fetch data once with Observables in Angular 2

I have a service, what is used several times from a lot of my Angular 2 components. It fetches customer data from a Web API and returns an Observable:

getCustomers() {
return this.http
.get(this.baseURI + this.url)
.map((r: Response) => {
let a = r.json() as Customer[];
return a;
});
}


I inject this service in my root component, and in every component that wants to access the customers I just subscribe to that Observable:

this.customerService.getCustomers().subscribe(v => this.items = v);


However, every component who subscribes to my Observable causes another execution of the HTTP-request. But to fetch the data only once is enough.
If I try share(), it does not solve my problem:

getCustomers() {
return this.http
.get(this.baseURI + this.url)
.map((r: Response) => {
let a = r.json() as Customer[];
return a;
}).share();
}


Still the same issue. Any proposals which operators I have to use to only fetch data once?

Answer

Why not to just save the downloaded data in your service?

SomeService {
  private customers;

  public getCustomers(): Promise<Object> {
    return new Promise((resolve, reject) => {
        if (!this.customers) {
            this.http
                .get(this.baseURI + this.url)
                .map((r: Response) => {
                    let a = r.json() as Customer[];
                    return a;
                }).do((data) => {
                    this.customers = data;
                    resolve(this.customers);
                }).catch(error => reject(error));
        } else {
            resolve(this.customers);
        }
    });
  }   
}

Since it returns a promise you need to change your assignment to:

this.customerService.getCustomers().then(v => this.items = v);