What I am trying to accomplish is to call external API only once per app initialization.
I have a simple service,
@Injectable()
export class XService {
url = "http://api.example.com"
constructor(private _http:Http) {
}
callAnAPI(){
console.log('made an external request");
return this._http.get(url)
.map(res=>res.json());
}
}
and two components, the main appComponent
@Component({
selector: 'my-app',
template: `
<div>
Test
</div>
`
})
export class AppComponent {
isLoading = true;
results = [];
constructor(private _service: XService){
}
ngOnInit(){
Observable.forkJoin(
this._service.callAnAPI()
// some more services here
)
.subscribe(
res => {
this.results = res[0];
},
null,
() => {this.isLoading = false}
);
}
}
and another component used with a route
@Component({
template: `
<div>
I want to use the service with this component.
</div>
`
})
export class SecondComponent {
constructor(private _service: XService){
}
}
the service is initialized and Angular hits server on the initialization of the AppComponent
. I want to Use XService
with SecondComponent
too, whenever I try to call the service again from the SecondComponent
, (via _service._service.callAnAPI()
) Angular hits the external API. I want to minimize the external hits.
How do I obtain the data made by the AppComponent
on initialization than calling again the service again in SecondComponent
You could use the do
operator for this to get the data the first time and reuse them for next calls:
@Injectable()
export class XService {
url = "http://api.example.com"
constructor(private _http:Http) {
}
callAnAPI(){
console.log('made an external request");
if (this.cachedData) {
return Observable.of(this.cachedData);
} else {
return this._http.get(url)
.map(res=>res.json())
.do((data) => {
this.cachedData = data;
});
}
}
}
If you want to load data as startup, you can call the callAnAPI
method from the service constructor.
To be able to use this approach, you need to define your service when bootstrapping your application:
bootstrap(AppComponent, [ XService ]);
This way you will use a single instance for your whole application.
@Injectable()
export class XService {
url = "http://api.example.com"
constructor(private _http:Http) {
}
callAnAPI(){
if(this.data) {
return Observable.of(this.data);
} else {
console.log('made an external request");
return this._http.get(url)
.map(res=>res.json())
.do(res => this.data = res);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With