Home > Net >  How to get the observable value inside a .map() function
How to get the observable value inside a .map() function

Time:11-29

I have a function _populateData that creates a new list of properties from another list of properties.

There is an observable getOwnerForProperty that returns the owner's value.

//Get single owner observable
public getOwnerForProperty(prop: any){
    return this._manageOwnerService._getOwnersOfProperty(prop).pipe(map(o => o[0]))

How can I call the observable from within the .map() function to obtain the observable's value and attach it to the new object as seen below? In my opinion, it would not be a good idea to subscribe getOwnerForProperty function in the .map(). Please advise on the best way to approach this following best practices.

/**
 * Returns the active properties data.
 * 
 * @param props - The property list.
 * @returns An array of properties 
 */
private _populateData(props: Property[]) {
    return
    const populated = props
        .filter(prop => !prop.isArchived)
        .map((p: Property) => {
            // refactoring here
            this.getOwnerForProperty(p).pipe(
                map((owner: Owner) => {
                    const obj = {
                        propertyName: p.info.name.toUpperCase(),
                        owner: owner.name,
                        createdOn: p.createdOn ? __FormatDateFromStorage(p.createdOn) : ''
                    } 
                    return obj;
                })
               
            )
            

        }
    )
    return populated;
}
}

CodePudding user response:

It's not entirely clear from your question what exactly you are trying to achieve, but here is my solution, so you will hopefully get the idea:

  1. filter for the properties you want to "enrich".
  2. use forkJoin to create an array of observables and wait for all of them to complete.
  3. map each property to the observable you want to wait for.
  4. map the result of the observable to the initial property and enrich it with the owner object.
  5. forkJoin returns an observable which will basically emit a single array of enriched objects and complete. If you wish to await this, you can wrap this in lastValueFrom operator, like await lastValueFrom(forkJoin(...))
function _populateData(props: Property[]) {
  const propertiesToPopulate = props.filter((prop) => !prop.isArchived);

  forkJoin(
    propertiesToPopulate.map((p: Property) => {
      return getOwnerForProperty(p).pipe(
        map((owner) => ({
          ...p,
          owner,
        }))
      );
    })
  );
}
  • Related