Обработка http-вызовов с ошибками внутри forEach - Angular 9 - PullRequest
0 голосов
/ 09 марта 2020

Я пишу кусок кода, который циклически перебирает массив и выполняет HTTP-вызовы.
Большинство этих HTTP-вызовов делается на несуществующие ресурсы, но я не знаю, какие именно.
В настоящее время я использую этот фрагмент кода:

    langs.forEach(lang => {
      this.http.get('assets/i18n/' + lang + '.json')
        .pipe(
          tap(data => console.log('server data:', data)),
          catchError(this.handleError),
        );
    });

В приведенном выше фрагменте кода ничего не отображается в консоли, хотя в действительности следует ожидать пару структур данных.
Я бы не ожидал, - это сообщения об ошибках типа: GET http://localhost: 4205/assets/i18n/[...] 404 (Not Found), а просто результаты успешных вызовов.
Интересно, как можно получить только хорошие структуры данных и отфильтровать ошибки в цикле.
Заранее спасибо.

РЕДАКТИРОВАТЬ :

this.handleError взято из angular документации:

private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message

    return throwError(
      'Something bad happened; please try again later.');
}

Ответы [ 2 ]

1 голос
/ 09 марта 2020

Я бы рекомендовал использовать forkJoin для параллельного выполнения нескольких HTTP-запросов. Если вы хотите обрабатывать ошибки по отдельным запросам, но по-прежнему возвращать ответы для других, вы можете добавить обработку ошибок для каждого отдельного запроса.

service.ts

getLanguages(): Observable<any[]> {
  const observables = langs.map(lang => {
    return this.http.get(`assets/i18n/${lang}.json`).pipe(
      catchError(() => of(null))
    );
  });

  return forkJoin(observables).pipe(
    // remove empty values from the array
    map(results => results.filter(x => !!x)),
  );
}

Затем вы добавите в ваш компонент и подпишитесь на функцию getLanguages().

component.ts

ngOnInit() {
  this.service.getLanguages().subscribe(responses => {
    console.log(responses); // [ {}, {}, {}, ... ]
  });
}
1 голос
/ 09 марта 2020

Если вам нужно сделать несколько звонков в течение 1 oop, я рекомендую вам использовать оператор ForkJoin rx js, помимо того, что он более элегантный, он также более выполнение всех звонков вместе.

const calls = [];
langs.forEach(lang => calls.push(this.http.get('assets/i18n/' + lang + '.json')));
Observable.forkJoin(calls).pipe(catchError(this.handleError)).subscribe(responses => {...});
...