Angular 13: Http Interceptor not Finalizing

Viewed 1018

I have a HtppInterceptor that starts and stops a progress bar in my app. This generally works fine for most Http requests, but I have a number of api calls and when these occur, the HttpHandler never finalizes, so the progress bar won't stop. I added a couple of log points to see which calls weren't getting finalised:

    intercept(
    req: HttpRequest<any>,
    next: HttpHandler
): Observable<HttpEvent<any>> {
    console.log('loading', req.url, this.handleRequestsAutomatically);

// If the Auto mode is turned off, do nothing
    if (!this.handleRequestsAutomatically) {
        return next.handle(req);
    }

    this._setLoadingStatus(true, req.url);

    return next.handle(req).pipe(
        finalize(() => {
            console.log('Finished Loading', req.url);

            this._setLoadingStatus(false, req.url);
        })
    );
}

The Api call creates the follow request:

:authority: localhost:5001
:method: GET
:path: /api/Appointments/ej?appointmentGroupId=1&year=2022&month=1&day=14
:scheme: https
accept: application/json
accept-encoding: gzip, deflate, br
accept-language: en-AU,en-GB;q=0.9,en-US;q=0.8,en;q=0.7
authorization: Bearer <token>
dnt: 1
origin: http://localhost:4200
referer: http://localhost:4200/
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/97.0.4692.71 Safari/537.36

I originally thought there must be some kind of connection kept open by the api call, but I can't see where that would be happening, and there is no "keep-alive" in the header request. The api call returns data correctly, I can't see the connection being kept open at either end.

Why isn't the HttpClient call completing and stopping my progress bar?

1 Answers

This was a design fault.

The issue was that inside the api library, there was another interceptor which was setting the user token in the header. Inside that interceptor, the HttpRequest object was being cloned.

As the first interceptor was waiting for the original request to finish, and the second interceptor was calling the request on the clone, the first request never completed.

Adding the loading indicator service to the second interceptor and calling the _setLoadingStatus(false, req.url) from there resolves the issue.

Edit: As chrisY points out, below, a better resolution is to change the order of the import statements so that the LoadingHttpInterceptor comes last. This way it is running off of the live HttpClient and the error doesn't occur.

Related