Sagi Sagi - 2 months ago 79
TypeScript Question

caching results with angular2 http service

I expose an HTTP GET request through a service, and several components are using this data (profile details on a user). I would like the first component request to actually perform the HTTP GET request to the server and cache the results so the the consequent requests will use the cached data, instead of calling the server again.

Here's an example to the service, how would you recommend implementing this cache layer with Angular2 and typescript.

import {Inject, Injectable} from 'angular2/core';
import {Http, Headers} from "angular2/http";
import {JsonHeaders} from "./BaseHeaders";
import {ProfileDetails} from "../models/profileDetails";

@Injectable()
export class ProfileService{
myProfileDetails: ProfileDetails = null;

constructor(private http:Http) {

}

getUserProfile(userId:number) {
return this.http.get('/users/' + userId + '/profile/', {
headers: headers
})
.map(response => {
if(response.status==400) {
return "FAILURE";
} else if(response.status == 200) {
this.myProfileDetails = new ProfileDetails(response.json());
return this.myProfileDetails;
}
});
}
}

Answer

Regarding your last comment, this is the easiest way I can think of : Create a service that will have one property and that property will hold the request.

class Service {
  _data;
  get data() {
    return this._data;
  }
  set data(value) {
    this._data = value;
  }
}

As simple as that. Everything else in the plnkr would be untouched. I removed the request from the Service because it will be instantiated automatically (we don't do new Service..., and I'm not aware of an easy way to pass a parameter through the constructor).

So, now, we have the Service, what we do now is make the request in our component and assign it to the Service variable data

class App {
  constructor(http: Http, svc: Service) {

    // Some dynamic id
    let someDynamicId = 2;

    // Use the dynamic id in the request
    svc.data = http.get('http://someUrl/someId/'+someDynamicId).share();

    // Subscribe to the result
    svc.data.subscribe((result) => {
      /* Do something with the result */
    });
  }
}

Remember that our Service instance is the same one for every component, so when we assign a value to data it will be reflected in every component.

Here's the plnkr with a working example.

Reference

Comments