Angular RxJs - заполнить массив во втором потоке (вложенный поток) - PullRequest
0 голосов
/ 03 ноября 2018

В моем приложении Angular есть список конкретной модели. Каждый элемент этого списка имеет свойство xyzList. Это свойство xyzList должно быть заполнено из запроса, который зависит от идентификатора первого запроса. Вот пример:

Модель

{
  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 голосов
/ 03 ноября 2018

Вам нужно использовать toArray (), потому что mergeMap / flatMap используется для сглаживания массива потока данных. Он вернет массив вместо пар данных.

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()
)
0 голосов
/ 03 ноября 2018

Ну, я так понимаю, у вас есть сервисная функция, которая возвращает список "предметов". Для каждого элемента необходимо вызвать другую сервисную функцию, которая возвращает данные «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));
...