Search code examples
javascriptangularrxjsrxjs-observables

How modify each Child object with adding data from Parent object when having the foreign key (from Parent) inside child Object?


How, in Dashboard Component, modify each Task Item from tasksCollection so that new Key(goalCategory) and Value being the category name from queried Goal Object (queried Goal based on foreign key) is added to each Task ? This is my attempt: https://pastecode.io/s/0srjkhqe

PS: I cut out any unnecessary code, such as getGoalById or tasksCollection definition so that only the most important code for the question remains.

// Dashboard Component
export class DashboardComponent implements OnInit {

goalCategory!:any; // parameter to which new value is supposed to be assigned with the help of getGoalCategory method on each iteration inside tasksArray

ngOnInit() {
    this.tasksService.tasksCollection()
    .pipe(
        concatMap(tasksArray => {

          tasksArray = tasksArray.map((item:any) => {
            this.getGoalCategory(item); // method which 
            return {
              goal_id: item.goal_id,
              description: item.description,
              id: item.id,
              isMainGoal: item.isMainGoal,
              name: item.name,
              goalCategory: this.goalCategory // -> new key with value from Goal!
            }
          })
          return tasksArray;
        })
    )
    .subscribe(
        (tasks:any) => {
          console.log(tasks);
        }
      )
}

}

Solution

  • You can use async and await to wait on getGoalCategory to complete. Using Promise.all you can wait until all goals are loaded

    Example setup:

    export class DashboardComponent implements OnInit {
        ngOnInit() {
            this.tasksService.tasksCollection()
                .pipe(
                    map(tasksArray => {
                        return tasksArray.map(async (item:any) => {
                            return {
                                ...item,
                                goalCategory: await this.getGoalCategory(item)
                            }
                        })
                    })
                )
                .subscribe(async tasks => {
                       const completedTasks = await Promise.all(tasks);
                       console.log(completedTasks);
                    }
                )
        }
    
        getGoalCategory(item:any) {
            return new Promise((res) => {
                this.goalsService.getGoalById(item.goal_id)
                    .subscribe(d => {
                        res(d[0].category);
                    })
            })
        }
    }