Search code examples
javascriptangularionic-frameworkhttpclientionic5

multiple http calls issue on Ionic (Angular) crashing


I have list of items in template

<ion-list class="ion-text-center">
    <div *ngIf="farms$ | async as farmData">
      <ion-item (click)="selectFarm(farm)" *ngFor="let farm of farmData" detail="true" button>
        <ion-label>
          <h2>{{ farm?.name }}</h2>
          <p>{{getNumberOfAnimals(farm?.id) | async}}</p>
        </ion-label>
      </ion-item>
    </div>
</ion-list>

In each item I need to get number of Animals from separate endpoint, which is separate call

getNumberOfAnimals(id){
const url = (some link) + id;
return this.http.get(url).pipe(take (1))
}

What is the issue - it is calling endpoint numbers of times (non stop until page crushes). Some of them even show as canceled.

Do you have any ideas why and how to fix that?


Solution

  • Here are my assumption for this answers

    • You don't have an API which accepts multiple ids.
    • FormData is not an observable.

    In that case I would recommend you not to call this method as calling from html is like calling from ngViewChecked it will call multiple time. Better get the numbers before and hold it into the array and call this from your html.

    Here is the sample code.

    // declared  variables in component 
    farmData: Array<any> = [];
    numberOfAnimals: Array<any> =[];
    
      ngOnInit(){
    
        const ids = of(this.farmData.map(elem => elem.id));
    
        // do not forget to unsubscribe
        ids.pipe(
          concatMap((val)=>{
            return this.getNumberOfAnimals(val).pipe(map((elem)=>{
              const item = {
                id: val,
                number: elem,
              }
             return this.numberOfAnimals.push(item);
            }))
          })
        ).subscribe();
      }
    
      getNumberOfAnimals(val): Observable<any>{
        // your api call
        return of({number: 20})
      }
    
    callFromYourHTML(id: number){
      return this.numberOfAnimals.find(elem => elem.id === id).number;
    }
    

    From your HTML call this

    <ion-list class="ion-text-center">
        <div *ngIf="farms$ | async as farmData">
          <ion-item (click)="selectFarm(farm)" *ngFor="let farm of farmData" detail="true" button>
            <ion-label>
              <h2>{{ farm?.name }}</h2>
              <p>{{callFromYourHTML(farm?.id) | async}}</p>
            </ion-label>
          </ion-item>
        </div>
    </ion-list>