I currently have the issue that my HTTP requests are stuck in a "pending" state (for more than 10 seconds until it starts the request).
This issue is especially common if I navigate to other pages with Angular's Route Navigation (routerLink='/dashboard/contact
as an example) - but it also occurs if I visit a page in the browser directly.
The API request getServerData
gets fired if a page gets loaded (constructor
method) or if route navigation is called - it's necessary for the page's content.
As you can see in my below code, I also have a simple caching system to avoid many HTTP requests, but that works as expected and is not the problem here.
Dashboard-Component, which calls the Service function:
getServerData(): void {
if (!this.dataService.active_guild) { return; }
if (!window.location.href.endsWith('/dashboard')) { return; }
forkJoin({guildUsage: this.apiService.getGuildUsage(100),
moduleStatus: this.apiService.getModuleStatus(this.dataService.active_guild!.id)})
.subscribe({
next: ({ guildUsage, moduleStatus }: { guildUsage: SliderItems[], moduleStatus: TasksCompletionList }): void => {
this.updateTasks(moduleStatus);
this.servers = guildUsage;
this.dataService.isLoading = false;
if (moduleStatus['task_1'].cached) { return; }
localStorage.setItem('moduleStatus', JSON.stringify(moduleStatus));
localStorage.setItem('moduleStatusTimestamp', Date.now().toString());
},
error: (err: HttpErrorResponse): void => {
if (err.status === 403) {
this.dataService.redirectLoginError('FORBIDDEN');
return;
} else if (err.status === 429) {
this.dataService.redirectLoginError('REQUESTS');
return;
} else if (err.status === 0) {
this.dataService.redirectLoginError('OFFLINE');
return;
}
this.dataService.isLoading = false;
}
});
}
Api-Service, which makes the HTTP request:
getGuildUsage(limit: number): Observable<SliderItems[]> {
return this.http.get<SliderItems[]>(`${this.API_URL}/stats/guilds_usage` + (limit ? `?limit=${limit}` : ''));
}
getModuleStatus(guild_id: string): Observable<TasksCompletionList> {
const moduleStatusTimestamp: string | null = localStorage.getItem('moduleStatusTimestamp');
const moduleStatus: string | null = localStorage.getItem('moduleStatus');
try {
if (moduleStatusTimestamp && moduleStatus) {
const timestamp: number = parseInt(moduleStatusTimestamp);
const module: TasksCompletionList = JSON.parse(moduleStatus);
// check if module status cache is younger than 1 minute
if (Date.now() - timestamp < 60000 && module['task_1'].guild_id === guild_id) {
module['task_1'].cached = true;
return of(module);
}
}
} catch (error) { console.error('Cache reading error:', error); }
return this.http.get<TasksCompletionList>(`${this.API_URL}/progress/modules?guild_id=${guild_id}`,
{ headers: this.authService.headers });
}
My API is also answering very fast, so I don't think that is the issue here.
For people who have the same issue:
It was fixed by using the ngOnDestroy
event of Angular. You need to unsubscribe from these requests because they are not canceled otherwise:
Example:
export class MyComponent implements OnDestroy {
private subscriptions: Subscription[] = []
ngOnDestroy(): void {
this.subscriptions.forEach(s => s.unsubscribe());
}
myApiFunction(feature_id: number, vote: boolean): void {
const feature_vote: Subscription = this.apiService.sendFeatureVote().subscribe({
next: (_data: any): void => {
// do something
},
error: (error: HttpErrorResponse): void => {
// do something
}
});
this.subscriptions.push(feature_vote);
}
}