Reputation: 368
I'm building an angular apps with api calls using httpclient, i don't use any package or plugin for that just httpclient.
Here's my example code in service.ts
getAdminMateriDetail(slug: any) {
return this._http.get(this.apiURL + 'admin/material/' + slug).pipe(
tap(console.log),
shareReplay(1),
tap(() => console.log('Materi Detail after sharing'))
)
}
i try to get materi detail from server, and in my component
getCurrentMateriDetail() {
return this.userService.getAdminMateriDetail(this.slug).subscribe(
(data:any) => {
this.currentMateri = data.data;
},
error => {
console.log(error);
}
)
}
ngOnInit() {
this.getCurrentMateriDetail();
}
i use that code in every page that needs data from server, but what i get is unexpected result, so when i navigate to component that calls an api and subscribe to that api, my component was blank for a couple seconds, sometime it's fast. I'm new using api calls, so is it normal? or maybe i can improve it to make it fast so user won't see a "blank page"?
I also read about caching, and i found shareReplay(1)
so i add it to my code but still blank for a couple of second. can someone give me the reason?
Upvotes: 0
Views: 924
Reputation: 1880
API calls always takes time. So you need to create loader or something like that. In component template you can do it with ngIfElse
:
<ng-container *ngIf="loadedData; else loader">
page content
</ng-container>
<ng-template #loader>Loading...</loader>
shareReplay
used for share result of "cold" (more info) observable between subscribers. But in your case it's useless, because every call of your function creates new Observable. Example:
// Correct usage:
const myMagicData$ = this._http.get(this.apiURL + 'admin/material/' + slug).pipe(
tap(console.log),
shareReplay(1),
tap(() => console.log('Materi Detail after sharing'))
);
myMagicData$.subscribe();
myMagicData$.subscribe();
In example above both subscriptions got same result. Without shareReplay()
every subscription triggers API call.
Upvotes: 1
Reputation: 3236
This is expected behavior, since you are doing an async call:
this.userService.getAdminMateriDetail(this.slug).subscribe(
(data:any) => {
this.currentMateri = data.data;
},
error => {
console.log(error);
}
)
Here, this.currentMateri
is null until the server responds (assume it to be between 0.1sec and 1 second). So in your HTML, you have to handle "what to do when this.currentMateri
is null ?"
To handle this, add *ngIf="currentMateri"
where you display asynchronous data, and add an other tag (div, or whatever) when *ngIf="!currentMateri"
, so you will display a loader, or anything...
Upvotes: 1