简体   繁体   中英

Handle http calls with errors inside a forEach - Angular 9

I'm writing a piece of code that cycles through an array and makes HTTP calls.
Most of these HTTP calls are made to non-existent resources, but I don't know which ones.
I'm currently using this piece of code:

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

The piece of code listed above shows me nothing in the console, when in reality a couple of data structures should be expected.
What I would not expect are error messages like: GET http://localhost: 4205/assets/i18n/[...] 404 (Not Found) , but simply the results of the successful calls.
I wonder how one can only get good data structures, and filter errors within a cycle.
Thanks in advance.

EDIT :

this.handleError is taken from the angular documentation:

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.');
}

If you need to make multiple calls in a for loop, I recommend that you use the ForkJoin rxjs operator, in addition to being more elegant, it is also more performing by making all the calls together.

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

I would recommend using forkJoin to run the multiple HTTP requests in parallel. If you want to handle errors on individual requests but still return responses for the others, you can add error handling to each individual request.

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)),
  );
}

You would then inject the service into your component and subscribe to the getLanguages() function.

component.ts

ngOnInit() {
  this.service.getLanguages().subscribe(responses => {
    console.log(responses); // [ {}, {}, {}, ... ]
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM