Issue
My interceptor code:
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent,
HttpErrorResponse,
HttpHeaders,
HttpResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { ApiService } from 'src/app/modules/services/api.service';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class HttpErrorService implements HttpInterceptor {
constructor(
private apiService: ApiService,
private router: Router,
) { }
intercept(request: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type',
})
});
return this.apiService.getSession().subscribe((res:any)=>{
if(res.data.existingSession == 'active'){
this.router.navigate(['/login']);
} else{
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
return event;
}),
catchError((error: HttpErrorResponse) => {
return throwError(() => { return 'Something bad happened; please try again later.' })
}));
}
});
}
}
I am trying to call an api before the interceptor intercept each api calls. But I am unable to add the valid return type & getting this error:
Type 'Subscription' is missing the following properties from type 'Observable<HttpEvent>': source, operator, lift, subscribe, and 3 more
Tried with switchMap.
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent,
HttpErrorResponse,
HttpHeaders,
HttpResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { ApiService } from 'src/app/modules/services/api.service';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class HttpErrorService implements HttpInterceptor {
constructor(
private apiService: ApiService,
private router: Router,
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type',
})
});
return this.apiService.getSession().pipe(
switchMap((res: any) => {
if(res.data.existingSession == 'active'){
this.router.navigate(['/login']);
} else{
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
return event;
}),
catchError((error: HttpErrorResponse) => {
return throwError(() => 'Something bad happened; please try again later.');
})
);
})
}
);
}
}
It's triggering the interceptor n number of time. But api calls are not happening. I need to call 1 api before interceptor intercepts each api calls.
Solution
Here is code example on stackblitz based on code you provided in your question. I think this would solved your problem.
If you want to use service api in interceptor I think you need to be sure that this api would be executed without using this interceptor; and the best or default way to do that is to use HttpBackend. of course you can see usage in this code example.
Just a note, I see you tried to use router.navigate() in your interceptor and I think it's not the best place for this kind of control. I can understand the need to define some logic through interceptor, but if you want to handle route redirection(related to session management) Angular guard would be better for that.
Hope this could be helpful.
Answered By - Oscar
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.