Как сохранить наблюдаемую цепочку, идущую после ошибки http в одной наблюдаемой - PullRequest
5 голосов
/ 06 февраля 2020

У меня есть цепочка наблюдаемых. Вот фрагмент кода:

        //get dynamic tree 
      flatMap(res => this.dynamicReportId !== null ? this.reportService.getDynamicTree(this.dynamicReportId) : of({})),
      tap(res => this.dynamicTree = res),
        //get dynamic report 
      flatMap((res) => this.dynamicReportId !== null ? this.reportService.getDynamicReport(this.dynamicReportId) : of({})),

Однако, когда я получил 500 ошибок API из первого запроса (получить динамическое дерево c), цепочка останавливается и никогда не входит во второй flatMap (Dynami c). отчет).

Вот функция this.reportService.getDynamicTree():

 get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
    return this.http.get(`${environment.apiBaseUrl}${path}`, {headers: this.setHeaders(true), params: params}).pipe(
      catchError(error => this.processError(path, error)),
      map((res: Response) => res));
  }

, где this.processError возвращает observableThrowError(res);

Что я должен вернуть в случае ошибки, чтобы продолжить цепь? Или причина в других вещах?

Ответы [ 2 ]

6 голосов
/ 17 февраля 2020

В случае ошибки Observable завершается, поэтому, если вы хотите вернуть новый Observable после возникновения ошибки, вы должны использовать оператор catchError, например:

//get dynamic tree 
flatMap(res => this.dynamicReportId !== null ? this.reportService.getDynamicTree(this.dynamicReportId) : of({})),
tap(res => this.dynamicTree = res),
catchError(() => of({})),
//get dynamic report 
flatMap((res) => this.dynamicReportId !== null ? this.reportService.getDynamicReport(this.dynamicReportId) : of({})),

Оператор tap безопасно не выполняет обратный вызов и просто пересылает ошибки, когда они возникают, поэтому присваивает this.dynamicTree только в случае успеха.

Если вы хотите обработать ошибку в вместо компонента, вы должны вернуть что-то еще, кроме observableThrowError(res); из processError (например, of({})), но это выполнит обратный вызов tap и назначит this.dynamicTree, что, вероятно, является нежелательным поведением.

2 голосов
/ 14 февраля 2020

Прежде всего - продолжение цепочки отчасти разрушает всю концепцию цепочки. Однако я думаю, что эта проблема должна быть решена с помощью довольно простого итератора цепочки и обработки ошибок, генерируемых HttpClient и сервисом.

Я создал пример StackBlitz с моим решением: https://stackblitz.com/edit/chain. Для просто города цепочка возвращает данные в { result: any, error: any }[]. Конечно, вы сможете делать практически все, что угодно с точки зрения операторов трубопроводов, чтобы скорректировать результат.

В идеале, функциональность observableChain должна быть отдельной и обрабатывать пустые результаты так, как вам нужно - в вашем case вместо возврата { result: any, error: any }[] вернет {} в ответе на ошибку и зарегистрирует ошибку

...