0
votes

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.

2

2 Answers

2
votes

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);
        })
    );
2
votes

The observables need to complete for the forkJoin to emit. If the observables are streams, you could use RxJS combineLatest and pipe in a take(1). Try the following

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