8

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.

2 Answers 2

15

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

2 Comments

This is exactly what I was looking for and answers my question - thanks
Is there any difference If I use forkJoin or simply call the same function in loop iteration?
4

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

UPDATE: See improved docs here:

https://rxjs.dev/api/index/function/forkJoin

3 Comments

Thanks for your answer - yes 'this' was the problem. Will look into using 'forkJoin' as well.
can you point out the benifits of forkJoin or simply calling method in forEach?
With forEach your code needs to subscribe to each Observable. That means you should also unsubscribe from each observable (which is not possible with the code as shown above.) With the forkJoin, you don't have to subscribe to any of the "inner" observables ... only to the "outer" forkJoin.

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.