La propriété 'catch' n'existe pas sur le type 'Observable <any>'

127

Sur la page de documentation Angular 2 pour l'utilisation du service Http, il y a un exemple.

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

J'ai cloné le projet angular2-webpack-starter et ajouté moi-même le code ci-dessus.

J'ai importé en Observableutilisant

import {Observable} from 'rxjs/Observable';

Je suppose que les propriétés Observablesont également importées ( .mapfonctionne). Regardé le changelog pour rxjs.beta-6 et rien n'est mentionné catch.

BrianRT
la source

Réponses:

246

Attention : cette solution est obsolète depuis Angular 5.5, veuillez vous référer à la réponse de Trent ci-dessous

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

Oui, vous devez importer l'opérateur:

import 'rxjs/add/operator/catch';

Ou importez de Observablecette façon:

import {Observable} from 'rxjs/Rx';

Mais dans ce cas, vous importez tous les opérateurs.

Voir cette question pour plus de détails:

Thierry Templier
la source
2
Savez-vous pourquoi les propriétés ne sont pas importées avec import {Observable} from 'rxjs/Observable';? Cela me semble plus intuitif.
BrianRT
6
Parce que Rxjs est conçu comme ça. Le rxjs/Observablemodule n'importe pas d'opérateurs car il y a beaucoup d'opérateurs. Le rxjs/Rxmodule importe tout ... Je pense que c'est un choix de conception.
Thierry Templier
4
l'importation de rxjs / Rx ralentit vraiment le chargement de la page. comparer le nombre de demandes avec lui v sans = la moitié des demandes lorsque vous n'utilisez pas rxjs / Rx mais utilisez par exemple rxjs / Observable
danday74
L'importation rxjs / Rx souvent ne peluche même plus, c'est une importation sur liste noire. Je sais que dans le passé, cela était considéré comme un peu correct (et je l'ai fait), mais de nos jours, cela ne devrait jamais faire partie d'une réponse correcte pour autre chose que jouer.
Tim Consolazio
93

Avec RxJS 5.5+, l' catchopérateur est désormais obsolète. Vous devez maintenant utiliser l' catchErroropérateur en conjonction avec pipe.

RxJS v5.5.2 est la version de dépendance par défaut pour Angular 5.

Pour chaque opérateur RxJS que vous importez, catchErrorvous devez maintenant importer depuis 'rxjs / operators' et utiliser l'opérateur de tube.

Exemple de capture d'erreur pour une requête 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) => {
        ...
      }
    )
  }
  ...
}

Notez ici qui catchest remplacé par catchErroret que l' pipeopérateur est utilisé pour composer les opérateurs de la même manière que ce à quoi vous êtes habitué avec le chaînage de points.


Consultez la documentation rxjs sur les opérateurs pipable (anciennement appelés louables ) pour plus d'informations.

Trent
la source
est map(res => res)nécessaire?
Pieter De Bie
1
Non, la pipefonction RxJS vous permet de combiner plusieurs fonctions en une seule fonction. La fonction pipe () prend comme arguments les fonctions que vous souhaitez combiner et renvoie une nouvelle fonction qui, lorsqu'elle est exécutée, exécute les fonctions composées dans l'ordre. Cette cartographie ne fait rien, car c'est techniquement une fonction d'identité.
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
la source