A propriedade 'catch' não existe no tipo 'Observable <any>'

127

Na página de documentação do Angular 2 para usar o serviço Http, há um exemplo.

getHeroes (): Observable<Stuff[]> {
  return this.http.get(this.url)
                  .map(this.extractData)
                  .catch(this.handleError);
}

Clonei o projeto angular2-webpack-starter e adicionei o código acima.

Eu importei Observableusando

import {Observable} from 'rxjs/Observable';

Estou assumindo que as propriedades Observablesão importadas também ( .mapfunciona). Observou o changelog do rxjs.beta-6 e nada é mencionado catch.

BrianRT
fonte

Respostas:

246

Aviso : esta solução está obsoleta desde o Angular 5.5, consulte a resposta de Trent abaixo

=======================

Sim, você precisa importar o operador:

import 'rxjs/add/operator/catch';

Ou importe Observabledesta maneira:

import {Observable} from 'rxjs/Rx';

Mas, neste caso, você importa todos os operadores.

Veja esta pergunta para mais detalhes:

Thierry Templier
fonte
2
Você sabe por que as propriedades não são importadas import {Observable} from 'rxjs/Observable';? Isso parece mais intuitivo para mim.
18730 BrianRT #
6
Porque o Rxjs foi projetado assim. O rxjs/Observablemódulo não importa operadores porque existem muitos operadores. O rxjs/Rxmódulo importa tudo ... Eu acho que é uma escolha de design.
Thierry Templier
4
importar do rxjs / Rx é realmente lento o carregamento da página. comparar contagem pedido com ele v sem = metade das solicitações quando u não usar rxjs / Rx mas o uso, por exemplo, rxjs / Observable
danday74
A importação rxjs / Rx frequentemente não é mais usada, é uma importação na lista negra. Eu sei que no passado isso era visto como um tipo de aprovação (e já fiz), mas hoje em dia nunca deve ser parte de uma resposta correta para outra coisa senão brincar.
Tim CONSOLAZIO
93

Com o RxJS 5.5+, o catchoperador agora está obsoleto. Agora você deve usar o catchErroroperador em conjunto com pipe.

O RxJS v5.5.2 é a versão de dependência padrão para o Angular 5.

Para cada Operador RxJS que você importa, incluindo catchErroragora você deve importar de 'rxjs / operadores' e usar o operador de tubulação.

Exemplo de captura de erro para uma solicitação HTTP Observable

import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
...

export class ExampleClass {
  constructor(private http: HttpClient) {
    this.http.request(method, url, options).pipe(
      catchError((err: HttpErrorResponse) => {
        ...
      }
    )
  }
  ...
}

Observe aqui que catché substituído por catchErrore o pipeoperador é usado para compor os operadores de maneira semelhante à que você está acostumado com o encadeamento de pontos.


Consulte a documentação rxjs em pipable (anteriormente conhecido como locável ) operadores para mais informações.

Trent
fonte
é map(res => res)necessário?
Pieter De Bie
1
Não, a pipefunção RxJS permite combinar várias funções em uma única função. A função pipe () usa como argumentos as funções que você deseja combinar e retorna uma nova função que, quando executada, executa as funções compostas em sequência. Esse mapeamento não faz nada, pois é tecnicamente uma função de identidade.
Trent
1
In angular 8:
for catch:
import { catchError } from 'rxjs/operators';

for throw:
import { Observable, throwError } from 'rxjs';

and code should be written like this.

getEmployees(): Observable<IEmployee[]> {
    return this.http.get<IEmployee[]>(this.url).pipe(catchError(this.erroHandler));
  }

  erroHandler(error: HttpErrorResponse) {
    return throwError(error.message || 'server Error');
  }
Prince Babbar
fonte