web-dev-qa-db-fra.com

Comment utiliser catchError () et toujours renvoyer un Observable typé avec rxJs 6.0?

cdDonc, j'essaie de migrer une partie de mon code Angular 5 vers 6, et je comprends la plupart des modifications requises pour que rxjs fonctionne à l'aide de l'opérateur .pipe (). Il fonctionne comme vous le feriez attendez-vous à des opérations "canalisables".

Cependant, le comportement de catchError() est différent de l'opérateur .catch(). Avant rxjs 6, j'utilisais l'opérateur .catch() pour transformer l'entrée d'erreur en un objet d'erreur cohérent qui peut ensuite être intercepté dans le fichier `.subscribe ().

getAlbums(): Observable<Album[]> {
     return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
           .map(albumList => this.albumList = albumList)
           .catch(new ErrorInfo().parseObservableResponseError);            
    }

new ErrorInfo().parseObservableResponseError est une fonction qui prend un objet d'erreur en entrée et analyse l'erreur d'entrée en un objet d'erreur plus simple avec un objet normalisé. Catch retourne Observable<any>:

parseObservableResponseError(response): Observable<any> {
    let err = new ErrorInfo();
    ...
    return Observable.throw(err);        
}

Cela fonctionnait très bien pour gérer facilement les erreurs jusqu'à rxjs5 - les erreurs sont essentiellement capturées dans le cadre du pipeline, puis jettent une structure d'erreur bien connue qui peut être capturée .subscribe() fonction d'erreur.

Déplacer ce même code vers rxjs 6 cependant et utiliser .pipe() J'essaie de faire ce qui suit:

getAlbums(): Observable<Album[]> {
    return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
                .pipe(
                    map(albumList => this.albumList = albumList),
                    catchError(new ErrorInfo().parseObservableResponseError)                        
                );           
}

Cependant, cela ne fonctionne pas car catchError retourne maintenant un résultat de Observable<any> Dans le pipeline, ce qui n'est pas ce que je veux ici. En substance, je veux simplement rejeter les erreurs comme je l'ai fait auparavant.

erreur TS2322: tapez 'Observable <{} | L'album []> 'ne peut pas être affecté au type' Observable '

Comment simuler l'ancien comportement de l'opérateur .catch()?

Mise à jour:

Après avoir fouillé un peu plus avec cela, le code tel qu'il est montré a juste commencé à fonctionner sans me donner d'erreur de construction. Honnêtement, je n'ai aucune idée pourquoi cela a échoué avec le message d'erreur auparavant, mais fonctionne maintenant. La suggestion de @cartant dans les commentaires est un moyen explicite de spécifier le résultat et cela fonctionne aussi.

10
Rick Strahl

Vous devriez pouvoir spécifier explicitement les paramètres de type à catchError pour indiquer qu'il ne renverra pas un observable qui émet une valeur - c'est-à-dire qu'il renverra Observable<never> - et lancera toujours:

getAlbums(): Observable<Album[]> {
    return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
        .pipe(
            map(albumList => this.albumList = albumList),
            catchError<Album[], never>(new ErrorInfo().parseObservableResponseError)
        );           
}

Ainsi, le type déduit de l'appel pipe sera Observable<Album[]>.

14
cartant