Właściwość „catch” nie istnieje w typie „Observable <any>”

131

Na stronie dokumentacji Angular 2 dotyczącej korzystania z usługi HTTP znajduje się przykład.

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

Sklonowałem projekt angular2-webpack-starter i sam dodałem powyższy kod.

Importowałem Observableza pomocą

import {Observable} from 'rxjs/Observable';

Zakładam, że właściwości Observablesą również importowane ( .mapdziała). Przejrzał dziennik zmian rxjs.beta-6 i nic o nim nie wspomniano catch.

BrianRT
źródło

Odpowiedzi:

248

Ostrzeżenie : to rozwiązanie jest przestarzałe od wersji Angular 5.5, zapoznaj się z odpowiedzią Trenta poniżej

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

Tak, musisz zaimportować operatora:

import 'rxjs/add/operator/catch';

Lub zaimportuj w Observableten sposób:

import {Observable} from 'rxjs/Rx';

Ale w tym przypadku importujesz wszystkie operatory.

Zobacz to pytanie, aby uzyskać więcej informacji:

Thierry Templier
źródło
2
Czy wiesz, dlaczego właściwości nie są importowane z programem import {Observable} from 'rxjs/Observable';? Wydaje mi się to bardziej intuicyjne.
BrianRT
6
Ponieważ Rxjs jest zaprojektowany w ten sposób. rxjs/ObservableModuł nie importuje operatorów, ponieważ istnieje wiele podmiotów. Do rxjs/Rximportu modułu wszystko ... Myślę, że jest to wybór projektu.
Thierry Templier
4
importowanie z rxjs / Rx bardzo spowalnia ładowanie strony. porównaj liczbę żądań z tym v bez = połowy żądań, gdy nie używasz rxjs / Rx, ale użyj na przykład rxjs / Observable
danday74
Import rxjs / Rx często nie będzie już nawet lint, jest to import z czarnej listy. Wiem, że w przeszłości było to postrzegane jako w porządku (i zrobiłem to), ale obecnie nie powinno to być częścią poprawnej odpowiedzi na cokolwiek innego niż zabawę.
Tim Consolazio
97

W wersji RxJS 5.5+ catchoperator jest przestarzały. Powinieneś teraz używać catchErroroperatora w połączeniu z pipe.

RxJS v5.5.2 jest domyślną wersją zależności dla Angular 5.

Dla każdego importowanego operatora RxJS, w tym catchErrornależy teraz importować z „rxjs / operatorzy” i używać operatora potoku.

Przykład wychwytywania błędu dla żądania 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) => {
        ...
      }
    )
  }
  ...
}

Zwróć uwagę, że catchjest on zastąpiony przez catchErrori pipeoperator jest używany do tworzenia operatorów w podobny sposób do tego, do czego jesteś przyzwyczajony z łańcuchem kropek.


Zobacz dokumentację rxjs na temat operatorów pipable (wcześniej znanych jako lettable ), aby uzyskać więcej informacji.

Trent
źródło
jest map(res => res)wymagane?
Pieter De Bie
1
Nie, pipefunkcja RxJS umożliwia połączenie wielu funkcji w jedną funkcję. Funkcja pipe () przyjmuje jako argumenty funkcje, które chcesz połączyć, i zwraca nową funkcję, która po wykonaniu uruchamia złożone funkcje w kolejności. To mapowanie nic nie robi, ponieważ jest technicznie funkcją tożsamości.
Trent
4
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');
  }
Książę Babbar
źródło