Reputation: 1893
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?
SECOND UPDATE:
Actually the first part (return of...) is not necessary to make it work, only the second (making it a lambda expression) is enough.
Upvotes: 0
Views: 102
Reputation: 953
Try this:
myApiCall(data:any): Observable<any> {
return this.http.post<any>(url, data).pipe(
catchError((err) =>
if (err.status===401){
// Redirect if unhautorized
this.router.navigate(['login']);
}
...
);
}
Note the lambda syntax of the error handler declaration. It is required in order to pass in the context (this). Without it the 'router' is not known hence the error. More details here
Upvotes: 1