0

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.');
}
3
  • What's this.handleError? Commented Mar 9, 2020 at 12:32
  • Maybe you are missing the subscribe to your service. Commented Mar 9, 2020 at 12:36
  • @KurtHamilton I edited the question. I got it from Angular's documentation. Commented Mar 9, 2020 at 12:36

2 Answers 2

1

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 => {...});
Sign up to request clarification or add additional context in comments.

Comments

1

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); // [ {}, {}, {}, ... ]
  });
}

14 Comments

Really excellent! If you also remove the outputs of this type from the console: GET http://localhost:4205/assets/i18n/zu.json 404 (Not Found) I'd say I approve of the answer!
Done :) It's a case of using the filter array function in an RxJS map to keep only the "truthy" values.
mmm this error appeared: ERROR TypeError: Cannot read property 'filter' of null and the logs like: GET http://localhost:4205/assets/i18n/zu.json 404 (Not Found) have not disappeared...
Ok. Do you think there is no way to handle the errors and prevent logs?
OK, so two things... 1. I've just realised I put the map in the wrong place. Sorry! 2. I've just checked and I don't see errors in the console when using catchError. Can you check this stackblitz, and toggle between true/false in the catchError to either catch or throw. stackblitz.com/edit/angular-mq2rkr
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.