Search code examples
angularangular-httpclient

Angular component when load data from server is blank for a couple seconds


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?


Solution

  • 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.