Search code examples
angularhttpclientangular-http-interceptorsfork-join

Angular Observable HttpInterceptor ForkJoin Not Working


I have seen multiple people mentioning issues about this but didn't find any solution for it. I made a HttpInterceptor to add the token to my requests. Since I am using Firebase for authentication, retrieving the token requires an observable. Everything works fine and the token gets added but it doesn't work if I combine multiple requests with forkJoin.

HttpInterceptor:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.auth.idToken.pipe(
        mergeMap((token: any) => {
            if (token) {
                request = request.clone({ setHeaders: { Authorization: `Bearer ${token}` } });
            }
            return next.handle(request);
        })
    );
}

Some service:

forkJoin(
    this._dataService1.fetch(),
    this._dataService2.fetch(),
).subscribe(
    ([dataService1Data, dataService1Data]) => {
        alert("Completed");  // <-------- This line of code is never reached
    }
)

Unfortunately, the line above in code is never reached, even though I see both of the requests completing successfully in the network tab. Could someone please give me a solution? (Both of the fetch methods from above fire an Http GET request.)

Edit:

this._dataService1.fetch().subscribe(data => {
    console.log(data);
});
this._dataService2.fetch().subscribe(data => {
    console.log(data);
});

The above code works perfectly fine. As I mentioned it does work for individual request but not for forkJoin.


Solution

  • forkJoin only emits when the Observable complete. However, your Observable interceptor never completes. Add take(1) operator to your interceptor:

    return this.auth.idToken.pipe(
            take(1),
            mergeMap((token: any) => {
                if (token) {
                    request = request.clone({ setHeaders: { Authorization: `Bearer ${token}` } });
                }
                return next.handle(request);
            })
        );