Mr.Milannist
Mr.Milannist

Reputation: 39

Transform data from one observable using another observable in angular rxjs

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;
}

Upvotes: 2

Views: 1587

Answers (2)

BizzyBob
BizzyBob

Reputation: 14740

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 };
    })
);

Upvotes: 3

OLO
OLO

Reputation: 471

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];
        }));
    }

Upvotes: 1

Related Questions