My implementation includes an interceptor that acts as a retry wrapper for expired access tokens:
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpRequest,
HttpHandler,
HttpInterceptor,
HttpHeaders,
} from '@angular/common/http';
import { Observable, EMPTY, throwError } from 'rxjs';
import { catchError, switchMap, take } from 'rxjs/operators';
import { Router } from '@angular/router';
import { AuthService } from '../services';
@Injectable()
export class UnauthorizedInterceptor implements HttpInterceptor {
constructor(
private router: Router,
private readonly authService: AuthService
) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error, caught) => {
if (error.status === 401) {
const newToken = this.authService.getNewToken();
const updatedReq = req.clone({
setHeaders: {
Authorization: `Bearer ${newToken}`,
},
});
return next.handle(updatedReq);
}
return EMPTY;
})
);
}
}
This implementation is working as intended.
However, the method getNewToken
is asynchronous and when I update the code to
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError(async (error, caught) => {
if (error.status === 401) {
const newToken = await this.authService.getNewToken();
const updatedReq = req.clone({
setHeaders: {
Authorization: `Bearer ${newToken}`,
},
});
return next.handle(updatedReq);
}
return EMPTY;
})
);
}
I am faced with the challenge of handling asynchronous operations within the catchError
function. What could be a suitable solution for this scenario?
P.S: The getNewToken
method can potentially be modified to return an observable instead of a promise, but I have not yet found a viable way to achieve this.
Update
The TypeScript error message states:
Type 'Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any> | Observable<...>>' is not assignable to type 'Observable<HttpEvent<any>>'.
Type 'HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any> | Observable<...>' is not assignable to type 'HttpEvent<any>'.
Type 'Observable<HttpEvent<any>>' is not assignable to type 'HttpEvent<any>'.ts(2322)
When using @ts-ignore
, the browser throws the following error:
EmptyError: no elements in sequence