Type 'void' is not assignable to type 'ObservableInput<{}>'
Solution 1
you have to return the Observable
return request
.map((res: Response) => res.json())
.catch((error: any) => {
// todo: log?
if (error.status == 500) {
this.alertService.showError(error.statusText);
} else if (error.status == 588) {
this.alertService.showAlert(error.statusText);
}
return Observable.throw(error.statusText);
});
Solution 2
Sometimes when you call catch without using arrow function like below
getUserList() {
return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
.catch(this.handleError);
}
handleError(error: Response) {
if (error.status == 500) {
this.router.navigate(['/login']);
} else {
return Observable.throw(error);
}
}
then it gives error of
ERROR TypeError: Cannot read property 'navigate' of undefined not getting this
Because in handleError function this object is not accessible..if you console this.router then you will get undefined.. so this object not working and not getting router all available methods
So you have to use arrow function here like below
getUserList() {
return this.http.get(this.constURL + '/api/url/here', this.headerOptions)
.catch(error => {
return this.handleError(error);
});
}
handleError(error: Response) {
if (error.status == 500) {
this.router.navigate(['/login']);
} else {
return Observable.throw(error);
}
}
Also if you have not mentioned return for handlerError function then it will throw error again like
Argument of type '(error: any) => void' is not assignable to parameter of type
So its necessary to type return for handlerError function.
Check here for in detail.He has explained code very well with all possible errors and solution of that..worked for me
Solution 3
This is an answer for angular 6 with RXJS 6.
In your request function, it would look similar to this. Note that catch
has been replaced with catchError
and Observable.throw
is now throwError
. Also in RXJS 6 we use pipe to join together a sequence of function we wish to perform instead of the dot chaining previously.
//In your service
getData(url: string): Observable<any> {
let options = this.getHTTPOptions();
return this.http.get<any>(url, options).pipe(
catchError( (err: any, caught: Observable<any>) => { return
throwError(this.generalErrorHandler(err, caught)) } ) );
}
Then you can have an error handler. The key is to specify the keyword return
in both the catchError
function above and return the error in the handler.
The arrow ( =>
) allows you to pass the context of the calling function into the error handler which means you can do cool things such as this.router.navigate(['someroute']);
(If you have the router imported in your service)
//In your service
generalErrorHandler(error: any, caught: Observable<any>): Observable<any> {
console.log('error caught: ', error);
if( error.error.status == "INVALID_TOKEN" || error.error.status == "MAX_TOKEN_ISSUE_REACHED"){
console.log('token has expired');
this.logout();
return error;
}
return error;
}
Some key imports to get this to work:
//Imports for the service
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Http, Response } from '@angular/http';
import { catchError, map } from 'rxjs/operators';
import { Observable, throwError, of} from 'rxjs';
And lastly to subscribe to the request to get your data:
//In your component, don't forget to import your service
let response$ = this.someService.getData('url here');
response$.subscribe(
data => { console.log('do stuff to data here', data); },
err => { console.log("couldn't get data, maybe show error to user"); },
() => { console.log('function that is called upon finish'); }
);
Solution 4
return Observable.throw(error);
The Observable. throw is deprecated use throwError operator like this in the interceptor
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
return next.handle(request).pipe(
catchError(err => {
if (err.status === 401) {
// remove Bearer token and redirect to login page
this.router.navigate(['/auth/login']);
}
return throwError( err );
}));
}
Comments
-
eestein almost 2 years
This error started to pop up after I migrated to TS 2.2.2, so I'm assuming that's the problem... The code did not stop working, but now I receive that error and I tried a few things like returning an empty observable, catching the re-thrown exception and returning an object, nothing seemed to work. Why is this happening now? Shouldn't it understand I'm re-throwing the exception and not expect a return? Am I misreading the error?
This is the complete error description:
Here's the complete code:
return request .map((res: Response) => res.json()) .catch((error: any) => { // todo: log? if (error.status == 500) { this.alertService.showError(error.statusText); } else if (error.status == 588) { this.alertService.showAlert(error.statusText); } Observable.throw(error.statusText); });
I tried returning the Observable, but my wrapper method expects a return of type
T
, which is the return of my deserialized request (map(...)
). If I do return thethrow
this is the error I get:[ts] Type 'Observable' is not assignable to type 'T'
I'm using:
- Angular4
- Typescript 2.2.2
-
eestein about 7 yearsHey thank you for your answer, I had tried that before. It doesn't work because my wrapper method expects a return of type T. Please check my updated question. I'm sorry I forgot to add that. Thanks again.
-
eestein about 7 yearsBougarfaoui, I'm marking this as answer, because I was able to find out the problem now :) After your answer I decided to look more carefully into the code and I should indeed be returning it (even though the concept is still a little bit weird to me, since it's being re-thrown), but the problem was the expected return of my wrapper method. Once I changed that to expect Observable<T> it worked. Thank you.
-
tshm001 almost 6 yearsYou really shouldn't paste a long snippet of production code from a different app unrelated to the OP's answer. It's confusing to the people reading the answer and it's a bit unhelpful to OP.
-
Prashant M Bhavsar over 5 yearsHi tshm001, i think i tried to explain code required for OP's question. Its not production code but made it readable by adding some actual services names..Please let me know if changes required, i will do..Thanks
-
VSO over 4 yearsNote that the command is now
Observable.throwError
(rather than just.throw
) after the RxJS update. -
Enrico over 2 yearsthrowError(response); or throw Error(err);
-
Jeremy Thille over 2 yearsI'm getting
Property 'throwError' does not exist on type 'typeof Observable'. ts(2339)
(RxJS 7.4) -
Jeremy Thille over 2 yearsI'm getting
Property 'throwError' does not exist on type 'typeof Observable'. ts(2339)
(RxJS 7.4). Same thing withthrow
.