Подтвердить что ты не робот

Тип '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
4b9b3361

Ответ 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'); }
);