Angular RxJs-在第二个流(嵌套流)中填充数组

时间:2018-11-03 09:13:19

标签: javascript angular typescript rxjs rxjs6

我在Angular应用程序中有一个特定模型的列表。该列表的每个项目都有一个属性xyzList。这个xyzList属性应该从一个请求中填充,该请求取决于第一个请求的ID。这里是一个例子:

模型

{
  id: number;
  name: string;
  xyzList: any[]
}

现在我有两个请求:

请求1 :填充模型,但不填充xyzList

this.myVar$ = this.myService.getElements<Model[]>();

请求2 :应填写xyzList

this.myService.getXyzElements<XyzModel[]>(idOfTheModelOfTheFirstRequest);

起初我以为是这样的:

this.myService.getElements<Model[]>()
.pipe(
  mergeMap(items => items)
  mergeMap(item => {
    return this.myService.getXyzElements<XyzModel[]>(item.id)
           .pipe(
             map(xyzList => {
               item.xyzList = xyzList

               return item;
             })
           )
  })
)

这不起作用,因为我已经弄平了我的列表,并且我需要一个Observable<Array[]>,但是我认为我想要实现的目标或多或少是明确的。我假设我可以使用forkJoin来实现此目的,但是我不知道如何实现。或者有没有办法将扁平化列表转换回列表?

2 个答案:

答案 0 :(得分:1)

您需要使用toArray(),因为mergeMap / flatMap用于展平数据流数组。它将返回一个Array而不是数据流。

this.myService.getElements<Model[]>()
.pipe(
  mergeMap(items => items)
  mergeMap(item => {
    return this.myService.getXyzElements<XyzModel[]>(item.id)
           .pipe(
             map(xyzList => {
               item.xyzList = xyzList

               return item;
             })
           )
  }),
  toArray()
)

答案 1 :(得分:0)

嗯,我知道您有一个返回“项目”列表的服务功能。您需要调用的EveryItem调用另一个返回数据“ xyzList”的服务函数。

因此,每个“项目”必须是一个调用,然后创建一个“调用”数组

    myService.getElements().pipe(
        switchMap(result=>{
          //We can not return the "list"
          let calls:Observable[]=[]
            //Before, the first calls was the own result
            calls.push(of(result));
            //Each result push the calls
            result.forEach(e=>{
                calls.push(myService.getXyzElements(e.id));
            })

            return forkJoin(calls).pipe(map(result=>{
               //in result[0] we have the list of items
               //In result[1] we have the Xyz of items[0]
               //In result[2] we have the Xyz of items[1]
               int i:number=0;
               result[0].map(x=>{
                  i++;
                  return {
                      ...x,
                      xyzList:result[i]
                  }
               })
               return result[0];
            }))
        })
    ).subscribe(res=>console.log(res));