2

I have two observables: cities and addresses. In my addresses array I have an object with a property city_code which has a value and a property city which is empty. In cities I have objects with both properties.

How can I transform the data in addresses? I want to get the value for city from the cities array by matching the city_code and put that value into the corresponding object in addresses.

addresses$ = this.store.select(getAddresses);
cities$ = this.citiesFacade.allCities$;

function getAddressesWithCityName() {
   // some code here
}

Address and City:

export interface Address {
   city_code: string;
   city: string; // in addresses$ this property is empty and I should get it from cities$
}

export interface City{
   city_code: string;
   city: string;
}
Linda Paiste
  • 38,446
  • 6
  • 64
  • 102
Mr.Milannist
  • 39
  • 1
  • 10

2 Answers2

2

You can use combineLatest() to create an observable stream that is always up to date based on multiple source streams.

Then, you can simply define addresses$ as follows, without the need for the getAddressesWithCityName() method:

addresses$ = combineLatest([this.store.select(getAddresses), this.cities$]).pipe(
    map(([addresses, cities]) => addresses.map(a => {
        const city = cities.find(c => c.city_code === a.city_code)?.city;
        return { ...a, city };
    })
);
BizzyBob
  • 12,309
  • 4
  • 27
  • 51
1

you can try something like this:

    function getAddressesWithCityName(): Observable<Address[]> {
      return forkJoin([addresses$, cities$])
        .pipe(map((results: [Address[], City[]]) => {
          results[0]
            .forEach((address: Address) => address.city = (results[1]
              .find((city: City) => city.city_code === address.city_code) as City)?.city);
          return results[0];
        }));
    }
OLO
  • 471
  • 4
  • 7