I want to have a generic way of handling exceptions, expecially 401's received from the backend. When I don't extract the catchError content, it works fine. However if I simply extract it to a specific function, then nothing gets injected in that function:
return this.http.request<T>(new HttpRequest('POST', this.appConfig.baseApiPath + url, file, {
reportProgress: true,
headers: headers,
params: urlParams
})).pipe(
catchError((err) => {
if (err.status === 401) {
this.router.navigateByUrl('/login?expired=true');
}
return Observable.throw(err || 'Server error')
})
);
This works! However I wanted to handle this redirect code in a function in order to reuse it by other methods.
Here I exported that into a function:
return this.http.request<T>(new HttpRequest('POST', this.appConfig.baseApiPath + url, file, {
reportProgress: true,
headers: headers,
params: urlParams
})).pipe(
catchError(this.handleHttpError),
);
handleHttpError(error: HttpErrorResponse) {
if (error.status === 401) {
this.router.navigateByUrl('/login?expired=true'); --> router is null!
}
return Observable.throw(error || 'Server error')
}
And that's where router (as well as other constructor injected services) are null if I use that way of working... could you suggest why?
The reason is that you're losing context. When function is declared in such way this
keyword is about scope of the function, not the whole class. Not to lose context you shoud use an arrow function:
handleHttpError = (error: HttpErrorResponse) => {
if (error.status === 401) {
this.router.navigateByUrl('/login?expired=true');
}
return Observable.throw(error || 'Server error')
}
a better approach is to bind 'this' to your call:
catchError(this.handleHttpError.bind(this))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With