Reputation: 133
I have an angular application where I periodically want to fetch data from my backend and show the updates in the UI. This is my backend service :
// _backendService
apiDashboardJobs(): Observable<any> {
return this._httpClient.get<any>(`${environment.apiUrl}/api/dashboard/jobs`);
}
My component code:
this.jobsOverview$ = interval(3000)
.pipe(
takeUntil(this.destroy$),
switchMap(response => this._backendService.apiDashboardJobs()),
map(response =>
[
{'status' :'Completed', 'number': response.completed, 'color': 'rgb(94,210,86)'},
//...
]
));
public trackByFn(index, item) {
return index;
}
ngOnDestroy(): void {
// Unsubscribe and complete the destroy$ subject
this.destroy$.next();
this.destroy$.complete();
}
My html code:
<tr *ngFor="let job of jobsOverview$ | async; trackBy: trackByFn" style="height: 30px;">
<td>
<div style.background-color="{{job.color}}"> </div>
</td>
<td>
{{job.status}}
</td>
<td>
{{job.number}}
</td>
</tr>
Now, this code seemed to work fine initially, but after some time the table does not render at all anymore and I see a bunch of these errors in the network tab:
Can someone guide me on how to fix this?
Upvotes: 1
Views: 228
Reputation: 23803
I disagree with Gilles's comment
Well if it's working fine at begining then I think the issue is more related to your server or directly your backend. There are probably some rate limiting which prevent the next requests to be treated
The screenshot shows that the requests are cancelled. Cancellation is done client side.
Looking at your code, you're using an interval (every 3s) and a switchMap. Meaning that if your server for any reason takes longer than 3s to reply, the next tick of your interval
will happen and switchMap
will cancel the ongoing request.
If you replace your switchMap
with an exhaustMap
, it should work as expected.
EDIT:
Also note that in order to avoid that back pressure in the first place, you could improve the code to:
Here's how I'd do it:
defer(() => this._backendService.apiDashboardJobs())
.pipe(retry({ delay: 3000 }), repeat({ delay: 3000 }))
.subscribe(() => console.log('Received answer'));
Here's a live demo where I also show that errors are handled as expected: https://stackblitz.com/edit/rxjs-uah45e?devtoolsheight=60&file=index.ts
Upvotes: 2