Reputation: 35
I need to unsubscribe
during a call but when I do this there is no HttpResponse
. This is a problem for me as I also am using an http
interceptor to catch when I should show a loading icon or not.
So in my specific component I have this:
if (this.testSubscription)
this.testSubscription.unsubscribe(); // Stop original http request when calling getTestDetails with other parameters
this.testSubscription = this.getTestDetails(param1, param2);
And my interceptor:
intercept(request: HttpRequest<any>, next: HttpHandler) {
this.totalRequests++;
console.log(' intercept totalRequests: ', this.totalRequests);
this.loadingService.isLoading.next(true);
return next.handle(request).pipe(
tap(res => {
if (res instanceof HttpResponse) {
// I need to get here even when unsubscribing !!!!
this.decreaseRequests();
}
}),
catchError(err => {
this.decreaseRequests();
throw err;
})
);
}
So I'm not really sure how I can trigger my intercept method to catch this when I unsubscribe
on the Subscription..
Any ideas are appreciated!
Upvotes: 1
Views: 149
Reputation: 11203
This code looks vaguely familiar. :D
As @martin pointed out, you can use the finalize
operator. In fact, I've done some testing and found out you don't even need to tap
operator to handle all use-cases:
return next.handle(request).pipe(
finalize(() => {
this.totalRequests--;
if (this.totalRequests === 0) {
console.log('set loading false');
}
})
);
I've updated the original answer to reflect this info.
PS: The solution you came up with might have a bug in case of an error. If you have two pending requests and one of them fails while the other one is still in progress, you'll have decreaseRequests()
run twice (one from catchError
operator and one from finalize
), which will set loading to false
even though there still is another request pending.
Upvotes: 1
Reputation: 35
Thanks to the comments I was able to fix my problem. I've changed my interceptor to:
intercept(request: HttpRequest<any>, next: HttpHandler) {
this.totalRequests++;
this.loadingService.isLoading.next(true);
return next.handle(request).pipe(
tap(res => {
//Removed code here
}),
catchError(err => {
this.decreaseRequests();
throw err;
}),
finalize(() => {
if(this.totalRequests > 0){
this.decreaseRequests();
} }
)
);
}
I've tested it thoroughly and it seems to be working for my purposes.
Upvotes: 0