La propiedad 'catch' no existe en el tipo 'Observable <any>'

127

En la página de documentación de Angular 2 para usar el servicio Http, hay un ejemplo.

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

Cloné el proyecto angular2-webpack-starter y agregué el código anterior.

Importé Observableusando

import {Observable} from 'rxjs/Observable';

Supongo que las propiedades también Observablese importan ( .mapfunciona). Miró el registro de cambios para rxjs.beta-6 y no se menciona nada al respecto catch.

BrianRT
fuente

Respuestas:

246

Advertencia : esta solución está en desuso desde Angular 5.5, consulte la respuesta de Trent a continuación

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

Sí, debe importar el operador:

import 'rxjs/add/operator/catch';

O importe de Observableesta manera:

import {Observable} from 'rxjs/Rx';

Pero en este caso, importa todos los operadores.

Vea esta pregunta para más detalles:

Thierry Templier
fuente
2
¿Sabes por qué no se importan las propiedades import {Observable} from 'rxjs/Observable';? Eso me parece más intuitivo.
BrianRT
66
Porque Rxjs está diseñado así. El rxjs/Observablemódulo no importa operadores porque hay muchos operadores. El rxjs/Rxmódulo importa todo ... Creo que es una opción de diseño.
Thierry Templier
44
importar desde rxjs / Rx carga de página realmente lenta. compare el recuento de solicitudes con v sin = la mitad de las solicitudes cuando no usa rxjs / Rx pero usa por ejemplo rxjs / Observable
danday74
La importación de rxjs / Rx con frecuencia ya no produce pelusa, es una importación en la lista negra. Sé que en el pasado esto fue visto como algo bueno (y lo he hecho), pero hoy en día nunca debería ser parte de una respuesta correcta para otra cosa que no sea jugar.
Tim Consolazio
93

Con RxJS 5.5+, el catchoperador ahora está en desuso. Ahora debe usar el catchErroroperador junto con pipe.

RxJS v5.5.2 es la versión de dependencia predeterminada para Angular 5.

Para cada Operador RxJS que importe, incluido catchErrorahora debe importar desde 'rxjs / operadores' y usar el operador de tubería.

Ejemplo de error de captura para una solicitud 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 aquí que catchse reemplaza con catchErrory el pipeoperador se utiliza para componer los operadores de manera similar a lo que está acostumbrado con el encadenamiento de puntos.


Consulte la documentación de rxjs sobre operadores pipables (anteriormente conocidos como lettable ) para obtener más información.

Trent
fuente
se map(res => res)requiere?
Pieter De Bie
1
No, la pipefunción RxJS le permite combinar múltiples funciones en una sola función. La función pipe () toma como argumentos las funciones que desea combinar y devuelve una nueva función que, cuando se ejecuta, ejecuta las funciones compuestas en secuencia. Ese mapeo no hace nada, ya que técnicamente es una función de identidad.
Trent el
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');
  }
Príncipe Babbar
fuente