Reputation: 24583
I am trying to replay a failed request once a token has been refreshed. Following this as a guide.
My http interceptor:
isRefreshingToken: boolean = false
tokenSubject: Subject<void> = new Subject<void>()
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(this.tokenRequest(req)).pipe(
catchError((error) => {
if (error instanceof HttpErrorResponse) {
if (error.status === HttpStatusCode.Unauthorized) {
if (!this.isRefreshingToken) {
this.isRefreshingToken = true
this.dialog.open(LoginDialog).afterClosed().subscribe(() => {
// at this point there is a new token in my token service
this.isRefreshingToken = false
this.tokenSubject.next()
})
}
return this.tokenSubject.pipe(
switchMap(() => {
return next.handle(this.tokenRequest(req))
})
)
}
}
return throwError(() => error)
})
)
}
tokenRequest(req: HttpRequest<any>): HttpRequest<any> {
const token = // get token from service
return req.clone({ headers: req.headers.set('Authorization', `Bearer ${token}`) });
}
This is working in that after logging in via a dialog the request that failed is replayed. However the subscribe is never firing from the client that made the original request.
return forkJoin({
stuff: httpService.getStuff(),
other: httpService.getOther(),
...
}).subscribe(() => {
// won't trigger unless both stuff and other complete
})
So it would seem that the observable that I return from the http interceptor is incorrect in the case of an error and token refresh. Any ideas?
Upvotes: 1
Views: 58
Reputation: 24583
My issue was with using forkJoin. I have updated the question to reflect that. Seems I misunderstood forkJoin in that all observables need to emit AND complete. Once I fixed that I was good. No issues with my interceptor.
combineLatest(
httpService.getStuff(),
httpService.getOther(),
)
.pipe(
take(1),
)
.subscribe() => {
// works
});
Upvotes: 0