Parallel HTTP requests in Angular 4

2019-05-08 18:31发布

问题:

I am building a simple weather app that uses a REST service to display current weather data in any city entered by the user.

The dashboard page should display the current weather in ~5 cities specified by the user.

So my question is - given an array of 5 cities, what is the best way to issue a call to the REST service (via Angular service) for each element in that array.

Here's a code excerpt from my initial attempt:

locations: string[] = ["Seattle", "Woodinville", "Krasnoyarsk", "Stockholm", "Beijing"];

...

ngOnInit() {

    this.locations.forEach(function(element) {
      this.weatherService.getWeather(element).subscribe((data) => {
        console.log(data);
      });
    });

  }

But this yields an error: Failed to compile.

c:/Projects/weather-app/src/app/components/dashboard/dashboard.component.ts (19,12): Property 'weatherService' does not exist on type 'void'.

I realize the 'forEach' is not going to work here - but what's the best practice for doing this in ng 4?

Thanks.

回答1:

This will map locations array in array of Observables, forkJoin will emit value, when all responses are in place

Observable
.forkJoin(this.locations
  .map((element) => this.weatherService.getWeather(element))
.subscribe((data) => console.log(data));


回答2:

The issue is that using the function keyword instead of an arrow function, you are losing what this means. Inside a function using the function keyword, this refers to the function and not to your component class.

Modify to something like this:

this.locations.forEach(element => {
  this.weatherService.getWeather(element).subscribe((data) => {
    console.log(data);
  });
});

Note: You could also consider using forkJoin to wrap multiple observables.

You can find docs on it here: https://www.learnrxjs.io/operators/combination/forkjoin.html

But the example here may be more helpful: rxjs with multiple forkjoin when doing http requests