简体   繁体   中英

Nested angular http observable calls

Been stuck on this problem for a little while now. What I am trying to achieve is to swap out the product ids with the http response from an api.

The appConfig response (simplified)

[
  {
    ...,
    hotspot: [
      {
        ...,
        data: {
          ...,
          products: [1234, 5678]
        }
      },
      {
        ...,
        data: {
          ...,
          products: [8910, 1112]
        }
      }      
    ]
  }
]

The code that I currently am using (really basic for now).

public readonly loadAppConfig$ = this._retailerSrv.retailer$.pipe(
    filter((retailer) => Boolean(retailer)),
    switchMap((retailer) =>
      combineLatest([
        of(retailer),
        this._roomConfigSrv.loadAppConfig$(),
        this._authSrv.getApiKey$(retailer),
      ])
    ),
    map(([retailer, appConfigs, authResponse]) => {
      return appConfigs.map((appConfig) => {
        this._authSrv.apiKey = authResponse.access_token;
        return {
          ...appConfig,
          hotspots: appConfig.hotspots.map((hotspotConfig) => {
            if (
              hotspotConfig.type === 'products' &&
              hotspotConfig.data.products
            ) {
              return {
                ...hotspotConfig,
                data: hotspotConfig.data.products.map((productId) =>
                  this._authSrv.getProductFromApi$(
                    productId,
                    retailer
                  )
                ),
              };
            }
            return {
              ...hotspotConfig,
            };
          }),
        };
      });
    }),
    tap(console.log)
  );

Which basically returns me with http observables in place of the product ids (not api responses).

Result from tap

[
  {
    ...,
    hotspot: [
      {
        ...,
        data: {
          ...,
          products: [Observable, Observable]
        }
      },
      {
        ...,
        data: {
          ...,
          products: [Observable, Observable]
        }
      }      
    ]
  }
]

I know there would be a simpler way to achieve this but I haven't found anything so far (tried promises etc). Any help would be much appreciated, and please let me know if you have any other questions.

Cheers

your code don't give any clue about your.json and what you want get it, but the idea it's always the same

  1. you make a call to get an array
  2. You create an array with elements you need search
  3. you make a forkJoin of this new elements
  4. you add the result to the first array

In pseudo code, use as "inspiration"

loadAppConfig.pipe(
switchMap(configData=>{
    ..here we has config..
    let products=[]; //we create an array with the products
    configData.hotspot.forEach(x=>{
       products=[...products,x.data.products] //we fill the array "products" 
    })
    return forkJoin(products.map(p=>loadProduct(p)).pipe( //we create an array of observables
        map(productResult=>{
            ..here change the "config" that is store in "configData"...
            ..using "productResult"...,e.g.
            configData.hotsport.forEach(x=>{
              const product=productResult.find(x=>p.key==x.data.product
               x.data.productData=product
            })
            ...finally...
            return configData
        }
    )  
}
))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM