I'm doing a web application in Angular v11.0.2. I need to do a HTTP call to show some information on screen. To save time and to take advantage of the async
pipe benefits, I'm using it in the template, but, it's causing multiple requests that never stops.
Service
export class MyDataService {
constructor(
private http: HttpClient,
) {
}
fetchMyEmployeeData(): Observable<any[]> {
return this.http.post<any[]>('ENDPOINT', {});
}
}
Component
export class MyAwesomeComponent {
constructor(
public myDataService: MyDataService,
) {
}
}
Template
<ng-container *ngIf="(myDataService.fetchMyEmployeeData() | async) as data">
</ng-container>
This causes multiple requests and never stops.
The same happens if I use *ngFor
:
<tr *ngFor="let d of (myDataService.fetchMyEmployeeData() | async)">
<td>.</td>
</tr>
I have tried the following this:
Using the shareReplay
operator:
fetchMyEmployeeData(): Observable<any[]> {
return this.http.post<any[]>('ENDPOINT', {}).pipe(shareReplay());
}
Using a simple div:
<div *ngIf="(myDataService.fetchMyEmployeeData() | async) as data">
</div>
I know that if I subscribe from the component and save the results in a local variable, I can call it in the template, but this is not my goal. Working example:
export class MyAwesomeComponent implements OnInit {
data: any[];
constructor(
public myDataService: MyDataService
) {
}
ngOnInit() {
// This is not my goal because I will need to handle the subscription life manually.
this.myDataService.fetchMyEmployeeData().subscribe(res => this.data = res);
}
}
I have also followed the recommendations given here:
- Multiple identical async pipe in Angular causing multiple http requests
- How can I prevent the Angular async pipe from making frequent server calls when no results come back?
I don't know exactly what causes this multiple requests and how can I avoid it.
My goal is to use the async
pipe in the template and do just one HTTP call.
myDataService.fetchMyEmployeeData().subscribe(); myDataService.fetchMyEmployeeData().subscribe()
in your ts file. Try to debug it. You will find out that eachfetchMyEmployeeData()
execution returns a new Observable – yurzuiasync
pipe in templates without this behavior. I mean, an advantage to use theasync
in template is to avoid handling the life of the subscription in the component. There is also a few tutorials out there that shows the same technique without experimenting my issue. What do you recommend? I'm confused. – RRGT19employeeData$ = this.myDataService.fetchMyEmployeeData()
in your component and you will be happy withemployeeData$ | async
in template. – yurzui