web-dev-qa-db-fra.com

Erreur de capture dans la conduite combinée des opérateurs de location louable

Nous venons de mettre à niveau l'une de nos applications vers la version Angular 5) et nous avons commencé à effectuer la transition vers opérateurs locables , comme indiqué dans la version 5.5 de rxjs.

Pour cette raison, nous avons réécrit nos pipelines observables dans la nouvelle syntaxe avec l'opérateur .pipe().

Notre code précédent ressemblerait à ceci, avec un .catch() à l'intérieur de .switchMap() afin de ne pas interrompre l'exécution des effets si une erreur est renvoyée.

@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.map((action: LoadData) => action.payload)
.withLatestFrom(this.store.select(getCultureCode))
.switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)
  .map(result => {
    if (!result) {
      return new LoadDataFailed('Could not fetch data!');
    } else {
      return new LoadDataSuccessful(result);
    }
  })
  .catch((err, caught) => {
    return Observable.empty();
  });
  );

Dans le cas d’une erreur renvoyée dans l’appel de la dataService, elle serait interceptée et traitée (la gestion des erreurs simplifiée ici).

Avec la nouvelle syntaxe et l’utilisation de .pipe(), nous avons maintenant cette

@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
  map((action: LoadData) => action.payload),
  withLatestFrom(this.store.select(getCultureCode)),
  switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)),
  map(result => {
    if (!result) {
      return new LoadDataFailed('Could not fetch data!');
    } else {
      return new LoadDataSuccessful(result);
    }
  })
  );

Comment puis-je, de la même manière, détecter les erreurs renvoyées dans le pipeline observable, en utilisant la nouvelle syntaxe?

25
Daniel B

Après refactorisation, vous avez déplacé map de la projection switchMap, de sorte que toute erreur ferme le flux externe. Pour que les deux flux soient équivalents, vous devez utiliser la méthode de projection pipe comme suit:

import { empty } from 'rxjs;

// ...

@Effect()
loadData$ = this.actions$
.ofType(LOAD_DATA)
.pipe(
  map((action: LoadData) => action.payload),
  withLatestFrom(this.store.select(getCultureCode)),
  switchMap(([payload, cultureCode]) =>
    this.dataService.loadData(payload, cultureCode)
      .pipe(
         map(result => {
           if (!result) {
             return new LoadDataFailed('Could not fetch data!');
           } else {
             return new LoadDataSuccessful(result);
           }
          }),
         catchError((err, caught) => {
           return empty();
         })
      )
  )
);
37
artur grzesiak