从另一个observable中的observable返回对象

时间:2017-02-22 11:50:42

标签: javascript angular rxjs observable rxjs5

我尝试从3个不同的REST端点获取数据。数据模型由主数据组成,并具有高级数组,其中包含2个(将来可能更多)对象。我想根据每个对象中指定的REST端点,为每个高级对象注入一个带有选项的Array。一切正常,从Observable as Object返回,除了附加选项,以Observables为单位。

简化数据:

{
 simple: {
   param: "searchQuery",
 },
 advanced: [
  {
   param: "food",
   optionsModel: {
     url: "http://address.com/food",      
     }
  },
  {
   param: "drinks",
   optionsModel: {
     url: "http://address.com/drinks",
     }
   }
  ]
}

食物和饮料具有相同的结构,包括名称和ID的对象:

 {
  data: [
   {
     name: "DR1",
     id: 1
   },
   {
     name: "DR2",
     id: 1
   },
   ...
  ]
 }

在我的数据模型中,我没有options []数组,所以我手动注入它。服务:

 searchConfiguration$: Observable<SearchConfiguration> = this.http
  .get(this._configURL)
  .map((config) => {
      let configuration = config.json();
      let advancedArray = configuration.advanced;

      if(advancedArray) {
        advancedArray.forEach(advanced => {
          advanced.options = [];
          advanced.options = this.http.get(advanced.optionsModel.url)
             .map((r: Response) => r.json().data
        })
      }
    return configuration;
  })

父组件:

getSearchConfig() {
  this.searchConfiguration$ = this._bundlesService.searchConfiguration$;
} 

然后我在html中有异步管道来订阅Observable。如何将我的选项作为实际数组添加到高级而不是作为流?

修改 - 解决方案

感谢马丁的回答,解决方案是将两个流展平并最终用forkJoin()

连接它们
  searchConfiguration$: Observable<SearchConfiguration> = this.http
  .get(this._configURL)
  .map((config) => config.json())
  .concatMap((configuration) => {
      let observables = configuration.advanced.map((advanced) => {
        return this.http.get(advanced.optionsModel.url)
          .map((r: Response) =>  r.json().data)
          .concatMap((options) => advanced.options = options)
      });
    return Observable.forkJoin(observables, (...options) => {
      return configuration;
    })
  });

1 个答案:

答案 0 :(得分:1)

我没有测试过,但我认为你能做到如下:

searchConfiguration$: Observable<SearchConfiguration> = this.http
  .get(this._configURL)
  .map((config) => config.json())
  .concatMap(configuration => {
    var observables = configuration.advanced.map(advanced => {
      return this.http.get(advanced.optionsModel.url)
         .map((r: Response) => r.json().data);
    });

    return Observable.forkJoin(observables, (...options) => {
      configuration.options = options;
      return configuration;
    });
  })