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>