I am using Angular 14 and making a post request to my json server using the pattern like this:
myApiCall(data:any): Observable<any> {
return this.http.post<any>(url, data).pipe(catchError(this.handleError));
}
( as specified in https://angular.io/guide/http)
And then wanted to add 401 (unauthorized) handling to handleError
so I added this block
if (error.status===401){//UnAthorized
this.router.navigate(['login']);
}
to my handleError like so:
private handleError(error: HttpErrorResponse) {
if (error.status===401){//UnAthorized
this.router.navigate(['login']);
}
...
return throwError(
() => new Error('Something bad happened; please try again later.')
);
}
I can see in debugger that this.router.navigate(['login']); is hit, but it does not navigate to the login screen. same code does work in another place. The error in chrome console is :
ERROR TypeError: Cannot read properties of (has file and line see below for details) undefined (reading 'router')
at handleError (line where this.router.navigate(['login']); is)
at catchError.js:10:39
at OperatorSubscriber._error (OperatorSubscriber.js:23:21)
...
The top in call stack in the error is the .subscribe after myApiCall...
So what happens to handleError when I call
this.router.navigate(['login']);
Does it cause a return? And if so what gets returned ?
UPDATE
After Igor's suggestion of adding
return of([])
AND declaring handleError with ()=>{} syntax instead of normal, it worked.
I wonder why the second part is needed. I still suspect it has something to do with how pipe works.
This works:
private handleError = (error: HttpErrorResponse) => {
if (error.status===401)//UnAthorized
{
this.router.navigate(['login']);
return of([]);
}
...
return throwError(
() => new Error('Something bad happened; please try again later.')
);
}
This does not
private handleError(error: HttpErrorResponse){
if (error.status===401)//UnAthorized
{
this.router.navigate(['login']);
return of([]);
}
...
return throwError(
() => new Error('Something bad happened; please try again later.')
);
}
After this.router.navigate instead of hitting return, control is transferred to the caller that results in an error that mentions router.
Why?
Have you tried returning an observable from the catchError
operator?
Rxjs needs it to continue piping and not throwing errors that may stop redirecting.
You can easily return it with the of
operator:
myApiCall(data:any): Observable<any> {
return this.http.post<any>(url, data).pipe(
catchError((err) =>
if (error.status===401){
// Redirect if unhautorized
this.router.navigate(['login']);
}
// after catchError the piping proceeds,
// you should handle the case where the observable is EMPTY
// (i.e. in this scenario an error occurred)
return of(EMPTY)
);
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments