Search code examples
javascriptangulartypescriptangular-resolverangular-activatedroute

Getting data for route resolver by making http requests such that the result of second one depends on the result of first one


I have a resolver in my routing module

{
    path: 'path1',
    component: FirstComponent,
    resolve: {
     allOrders: DataResolver
    }

}

And then in my resolve function there is

resolve(): Observable<Array<string>> {

    return this.serviceA.getAllfooNames()
    .map(result=> {

         /* result is an array of strings*/
         return this.serviceB.getAllBarNames(result[0])

         /*orders is also supposed to be an array of strings*/     
          .map(orders=> return orders)                        
    });

 }
}

I want the value orders to be stored against the allOrders key. I want pass orders array as data in the ActivatedRoute snapshot. Please Help.


Solution

  • You can use a mix of concatMap and zip:

    resolve(): Observable<Array<string>> {
      return this.serviceA.getAllfooNames().pipe(
        concatMap((names) => 
          zip(...names.map((name) => this.serviceB.getAllBarNames(name)))
        ),
        map((...names) => 
          names.reduce((acc, curr) => acc.concat(curr), [])
        ) 
      ); 
    }
    

    This will return all the strings returned from the serviceB call, in one big array of strings.

    Basically what it does, you call getAllfooNames, with concatMap you wait until this request is finished, which returns a bunch of names in a string. After that you pick these up with the zip operator. This operator executes all the observables passed in there using the array map method, and emits once all of them are completed.

    This is then picked up in the map, which receives multiple string arrays as parameters. You then use reduce to make it in one big array.