Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular HttpClient makes multiple http request when only 1 http request is expected

Tags:

angular

I am expecting only one http request but in my console I am getting multiple http calls. I am not entirely sure the reason. Below is a abbreviated for ease of readability.

component.html

{{ (user | async).firstname }}  {{ (user | async).firstname }}

<ul>
  <li *ngFor="let profile of (user | async)?.profiles "> 
    <div>
        <p>{{ profile.profileType }}<span *ngIf="isStudent(profile.specialized)"> - {{ profile.specialized }}</span></p>
        <p>{{ profile.id }}</p>
    </div>

    <button class="btn btn-primary float-right" (click)="onGo(profile)">Go</button>
  </li>
</ul>

component.ts

private user: Observable<User>;

ngOnInit(){

   this.user = this.userDataService.fetchUserDetails(+params['id']);

}

UserDataService.ts

fetchUserDetails(id:number):Observable<User> {
console.log("calls 1 ?"); // this only gets called once!!!
return this.httpClient.get<User>(this.apiUrl + "/" + id)
  .pipe(
    tap((response) => {

      console.log(response); // this is executed multiple times!!!


      return response;
    }),
    catchError( (error) => {
      handleIt();
    })
  )

}

In my console

enter image description here

In my network

enter image description here

What is making HttpClient to make so many http requests? when the UserDataService clearly only been executed once...

like image 203
Eric Huang Avatar asked Jun 22 '18 08:06

Eric Huang


People also ask

What is the difference between HttpClient and HttpClient?

http is high level and HttpClient is low level (source) http can make post requests but HttpClient can't (source) both http and HttpClient (with HttpClientRequest ) can make GET and POST requests (source) both http and HttpClient can be used on the client and the server.

How do I stop multiple API calls?

How do I stop multiple API calls? On clicking on tabs you interchange state and you use ngOnInit() method every time when a state is changed to get the data.In this way, you can reduce API calls by using nested routing.

What is the difference between HttpClient and HTTP in Angular?

The HttpClient is used to perform HTTP requests and it imported form @angular/common/http. The HttpClient is more modern and easy to use the alternative of HTTP. HttpClient is an improved replacement for Http. They expect to deprecate Http in Angular 5 and remove it in a later version.


2 Answers

Every async pipe creates its own subscription to the observable, which ends in seperate API calls. You've got two options to solve it.

Option 1: Work with the as operator to save the result like this:

<ng-container *ngIf="user | async as u">
 {{ u.firstname }}
 ...
</ng-container>

Option 2: Work with the share operator from rxjs:

return this.httpClient.get<User>(this.apiUrl + "/" + id)   .pipe(
  tap(console.log), // this is executed multiple times!!!
    share(),
    catchError( (error) => {
      handleIt();
    })
);
like image 106
Markus Kollers Avatar answered Oct 21 '22 09:10

Markus Kollers


More use of async pipe will affect the efficiency because it will subscribe to every async pipe. You can notice this more if you are calling an HTTP service because it will call the HTTP request for each async pipe.

{{ user.firstname }}  {{ user.firstname }}

<ul>
  <li *ngFor="let profile of user?.profiles "> 
    <div>
        <p>{{ profile.profileType }}<span *ngIf="isStudent(profile.specialized)"> - {{ profile.specialized }}</span></p>
        <p>{{ profile.id }}</p>
    </div>

    <button class="btn btn-primary float-right" (click)="onGo(profile)">Go</button>
  </li>
</ul>


ngOnInit() {
    this.userDataService.fetchUserDetails(+params['id']).subscribe(data => this.user = data);
}
like image 39
Rahul Sharma Avatar answered Oct 21 '22 10:10

Rahul Sharma