Search code examples
javascriptangulartypescriptrxjs

How to await forkjoin.subscribe to use the values


This is a continuation from this post but I am creating a new post as it is different the original question.

Question - How to await forkjoin to complete before I run other business logic.

Code Below

export interface indexLogic {
  [id: number]: Detail;
}
async ngOnChanges(){
    await getData(); 
    //How to make sure below method only executes 
    //when this.indexLogic is populated.
    await useInformationReceivedFromgetData(); 
}
async getData(){
  getInformations().subscribe(
    informations => {
      let subs = [];
      for (const information of informations) {
         subs.push(getOtherDetails(information.id).pipe(
            map(data => ({ id: information.id, data })) // <---
         ));
      }
        this.indexLogic = [];
          forkJoin(subs).subscribe(objects => {           
             objects.forEach(({id, data}) => { this.indexLogic.push({[id]:data}) });
          });
       }
    
    );
}

Solution

  • To ensure that the forkJoin operation is completed before running other business logic, you can make use of the toPromise method and await the result.

    export interface indexLogic 
    {
        [id: number]: Detail;
    }
    
    async ngOnChanges() 
    {
        await this.getData();
        await this.useInformationReceivedFromgetData();
    }
    
    async getData() 
    {
        const informations = await getInformations().toPromise();
        const subs = [];
        for (const information of informations) 
        {
            subs.push(getOtherDetails(information.id).pipe(
            map(data => ({ id: information.id, data }))
            ));
         }
    
         this.indexLogic = [];
         const objects = await forkJoin(subs).toPromise();
         objects.forEach(({ id, data }) => 
         {
              this.indexLogic.push({ [id]: data });
         });
    }
    
    async useInformationReceivedFromgetData()  
    {
       // Business logic that depends on this.indexLogic being populated
    }
    

    the getData method is modified to use the toPromise method instead of subscribing to the observable directly. This allows you to await the result and ensure that the asynchronous operations are completed before moving forward. the forkJoin operation is also converted to a promise using toPromise to make it awaitable. The result is then stored in the objects variable, and the business logic in the useInformationReceivedFromgetData method can be executed safely knowing that this.indexLogic has been populated.