I have a template:
<mat-card *ngFor="let cargo of cargos" class="cont-mat">
...
<mat-checkbox *ngFor="let truck of (getTrucksByUserIdAndRules(cargo.id) | async)" formControlName="truckId">{{truck.regNumber}}</mat-checkbox>
Component
getTrucksByUserIdAndRules(cargoId: string) {
return this.cargosService.getTrucksByUserIdAndRules(this.userId, cargoId).pipe(
map(response => {
console.log(response.trucks);
return response.trucks;
})
)
}
and service:
getTrucksByUserIdAndRules(userId: string, cargoId: string): Observable<any> {
const url = BACKEND_URL_2 + "getTrucksByUserIdAndRules/" + userId + "/" + cargoId;
return this.http.get(url).pipe(
map(response => {
return response;
})
);
}
I want to fetch the list of trucks in my template based on a parameter cargo.id. I’m getting data from backend but the function getTrucksByUserIdAndRules(cargo.id) is called multiple times. I know this is not a good practise to use functions inside template and any other solution will be welcome.
Advertisement
Answer
In your constructor/ngOnInit component, load all the data. Note that you should do that in a resolver, it will be processed before the component is shown on your browser. You can check out more about resolver here.
trucksByCargoId: Map<number, Trucks>;
constructor(private yourService: YourService) {
this.trucksByCargoId = new Map();
this.cargos.forEach(cargo => {
// note that I dont recommand making HTTP call inside a loop, you should make only one HTTP call for all the cargo
this.yourService.getTrucksByUserIdAndRules(cargo.id).subscribe(result => {
trucksByCargoId.set(cargo.id, result);
});
}
}
and in your HTML template, retrieve the trucks corresponding to the cargo with the Map you created in your component
<mat-card *ngFor="let cargo of cargos" class="cont-mat">
...
<mat-checkbox *ngFor="let truck of trucksByCargoId.get(cargo.id)" formControlName="truckId">{{truck.regNumber}}</mat-checkbox>