Reputation: 23
I just copied this code from a tutorial
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError, BehaviorSubject } from 'rxjs';
import { AuthService } from './shared/auth.service';
import { catchError, switchMap } from 'rxjs/operators';
import { LoginResponse } from './login-response.payload';
@Injectable({
providedIn: 'root'
})
export class TokenInterceptor implements HttpInterceptor {
isTokenRefreshing = false;
refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject(null);
constructor(public authService: AuthService) { }
intercept(req: HttpRequest<any>,
next: HttpHandler): Observable<HttpEvent<any>> {
if (this.authService['getJwtToken']()) {
this.addToken(req, this.authService['getJwtToken']());
}
return next.handle(req).pipe(catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 403){
return this.handleAuthErrors(req, next);
} else {
return throwError(error);
}
}))
}
private handleAuthErrors(req: HttpRequest<any>, next: HttpHandler) {
if (!this.isTokenRefreshing) {
this.isTokenRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService['refreshToken']().pipe(
switchMap((refreshTokenResponse: LoginResponse) => {
this.isTokenRefreshing = false;
this.refreshTokenSubject.next(refreshTokenResponse.authenticationToken);
return next.handle(this.addToken(req,
refreshTokenResponse.authenticationToken));
})
)
}
}
private addToken(req: HttpRequest<any>, jwtToken: string) {
return req.clone({
headers: req.headers.set('Authorization',
'Bearer ' + jwtToken)
});
}
}
and i'm receiving this error
'The type 'Observable<unknown>' is not assignable to type
'Observable<HttpEvent<any>>
Type 'unknown' is not assignable to type 'HttpEvent<any>'.
The error is caused here
return next.handle(req).pipe(catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 404){
return this.handleAuthErrors(req, next);
} else {
return throwError(error);
}
}))
What should I change to make it work?? (this the article btw https://programmingtechie.com/2020/04/05/build-a-full-stack-reddit-clone-with-spring-boot-and-angular-part-13/#Refresh_Token_Process_-_Step_by_Step)
Upvotes: 2
Views: 1228
Reputation: 1666
I tried to analyze your code, however I was unable to understand the reason. If you are looking for a solution, you can add the return type Observable<HttpEvent<any>>
to the function signature as follows:
private handleAuthErrors(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
See the file check.js in a mock angular playground on stackblitz
This will solve your issue which comes from the usage of switchMap
see related post
Also, according to this, might be related to recent switch between rxjs versions. Try to restart IDE and clear cached node_modules
Upvotes: 1
Reputation: 10954
The compiler can't figure out the return type of handleAuthErrors
because not all paths return a value. I don't know what the author intends to happen when the token is refreshing, but you can just return EMPTY
.
private handleAuthErrors(req: HttpRequest<any>, next: HttpHandler) {
if (!this.isTokenRefreshing) { ... }
return EMPTY;
}
Upvotes: 1
Reputation: 93
Check out this similiar question:
There are two problems here, you need to typecast return to your output, also finalize is missing from imports.
I hope I could help you!
Kind regards Sebastian
Upvotes: 1