angularsettimeoutangular2-observablesfork-join

Force nested loop over observables to wait for all


I've read about forkJoin, async, await, and also tried out angular life cycle methods, but finally found no good solution.

I need to wait until initiAttributesMap has finished his job before next code lines run. If I use a setTimeout I get the map fully filled. But I want to avoid setTimeout. Thank you.

somewhereInCode (){
    initAttributesMap();        
    setTimeout(() => {
        //do Other things                
            }, 20);
}

public initAttributesMap(bObjects: BObjects[], attributesMap: Map<string, string>){
    bObjects.forEach( (bObject: BObjects) => {
        if ( bObject.cValues !== null ) {
            bObject.cValues.forEach( ( cValue: CValue ) => {
                this.myService.getValueTypes( cValue.source).subscribe(
                        ( possibleValues: PossibleValues[] ) => {                                
                            let displayName = possibleValues.find( foundValue => cValue.id == foundValue.id ).displayName;
                            attributesMap.set( cValue.attributeName, displayName );
                        } );
            });
        }
   });

}


Solution

  • If you want wait while all attributes will be initialized:

    somewhereInCode (){
      initAttributesMap().subscribe(() => {
        //do Other things
      });        
    }
    
    public initAttributesMap(bObjects: BObjects[], attributesMap: Map<string, string>){
      const resObs: Observable<unknown[]> = []
      bObjects.forEach( (bObject: BObjects) => {
        if (bObject.cValues !== null) {
          bObject.cValues.forEach( ( cValue: CValue ) => {
            const obs = this.myService.getValueTypes( cValue.source).pipe(
              tap(( possibleValues: PossibleValues[] ) => {
                let displayName = possibleValues.find( foundValue => cValue.id == foundValue.id ).displayName;
                attributesMap.set( cValue.attributeName, displayName );
              })
            )
            resObs.push(obs);
          });
        }
      });
      return forkJoin(...resObs);
    }