2
votes

I have two separate functions returning different observables.

getCities(): Observable<City[]>

For example [{city: 'Amsterdam'}, {city: 'Rotterdam'}]

getLocations(city: string): Observable<CityLocation[]>

For example getLocations('Amsterdam') will return [{location: 'Westpoort'}, {location: 'Amsterdam-Noord' }]

I would like to combine these two and have a function to return an observable like this:

[ {city: 'Amsterdam', locations:[{location: 'Westpoort'}, {location: 'Amsterdam-Noord'}]}, {city: 'Rotterdam', locations: [{...}, {...}]} ]

So basically the function should loop through the cities, then for each city it should get the locations and merge everything into one observable.

This is what I have now:

getCombined() { return this.getCities().pipe( mergeMap(cities => { return from(cities).pipe( mergeMap( city => this.getLocations(city.city), (original, detail) => ({ ...original, locations: detail }) ), toArray(), map(locations => ({ ...cities, locations })) ); }) ); }

But unfortunately it doesn't work and no errors in the console. I'm not sure what I'm doing wrong.

EDIT:

Stackblitz editor: https://stackblitz.com/edit/angular-32wman

1
Create a sample on Stackblitz to give us a better idea. - Yash Krishan
OK one moment please - Rafff

1 Answers

1
votes

You can use forkJoin for the requests and also add the locations as an array for each city, as you want per my understanding. Your modified code:

getCombined() {
  return this.getCities().pipe(
    mergeMap(cities => forkJoin(
      cities.map(c => this.getLocations(c.city).pipe(
        map(locations => {
          c.locations = locations;
          return c;
        })
      ))
    ))
  );
}

STACKBLITZ