首页 文章

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

提问于
浏览
2

我尝试从3个不同的REST endpoints 获取数据 . 数据模型由主数据组成,并具有高级数组,其中包含2个(将来可能更多)对象 . 我想根据每个对象中指定的REST endpoints ,为每个高级对象注入一个带有选项的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 . 如何将我的选项作为实际数组附加到高级而不是作为流?

Edit - Solution

感谢martin的回答,解决方案是将两个流展平并最终用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 回答

  • 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;
        });
      })
    

相关问题