Тип 'void' не присваивается типу 'ObservableInput <{}>'
Эта ошибка начала появляться после перехода на TS 2.2.2, поэтому я предполагаю, что проблема... Код не переставал работать, но теперь я получаю эту ошибку, и я пробовал несколько вещей, таких как возвращение пустой наблюдаемый, поймавший переброшенное исключение и возвращающее объект, ничего не работало. Почему это происходит сейчас? Разве он не понимает, что я перебрасываю исключение и не ожидаю возврата? Я неправильно понял ошибку?
Это полное описание ошибки:
![введите описание изображения здесь]()
Здесь полный код:
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);
});
Я попытался вернуть Observable, но мой метод-оболочка ожидает возврата типа T
, который является возвратом моего десериализованного запроса (map(...)
). Если я возвращаю throw
, то это ошибка, которую я получаю:
[ts] Тип 'Observable' не присваивается типу 'T'
Я использую:
- Angular4
- Typescript 2.2.2
Ответы
Ответ 1
вам нужно вернуть 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);
});
Ответ 2
Иногда, когда вы вызываете catch без использования функции стрелки, как показано ниже
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);
}
}
тогда это дает ошибку
ОШИБКА TypeError: Невозможно прочитать свойство 'navigate' из неопределенного, не получив это
Потому что в функции handleError этот объект недоступен.. если вы утешите this.router, вы получите неопределенное значение.. поэтому этот объект не работает и не получает маршрутизатор всеми доступными методами
Таким образом, вы должны использовать функцию стрелки здесь, как показано ниже
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);
}
}
Также, если вы не упомянули return для функции handlerError, она снова выдаст ошибку
Аргумент типа '(error: any) => void' нельзя назначить параметру типа
Поэтому необходимо ввести return для функции handlerError.
Проверьте здесь подробно. Он объяснил код очень хорошо со всеми возможными ошибками и решением этого.. работал для меня
Ответ 3
Это ответ для angular 6 с RXJS 6. В вашей функции запроса это будет выглядеть примерно так. Обратите внимание, что catch
был заменен catchError
а Observable.throw
теперь throwError
. Также в RXJS 6 мы используем pipe для объединения последовательности функций, которые мы хотим выполнить, вместо цепочки точек ранее.
//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)) } ) );
}
Тогда вы можете иметь обработчик ошибок. Ключ должен указать ключевое слово return
в функции catchError
описанной выше, и вернуть ошибку в обработчик. Стрелка (=>
) позволяет вам передавать контекст вызывающей функции в обработчик ошибок, что означает, что вы можете делать классные вещи, такие как this.router.navigate(['someroute']);
(Если у вас есть роутер, импортированный в ваш сервис)
//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;
}
Некоторые ключевые импорта, чтобы заставить это работать:
//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';
И, наконец, чтобы подписаться на запрос, чтобы получить ваши данные:
//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'); }
);