Вложенные подписки в Angular с итерацией по первому результату - PullRequest
0 голосов
/ 18 ноября 2018

С этого утра я пытаюсь решить действительно головную боль.

Я начну с объяснения (очень простой) ситуации.

Я создал группы, которые состоят из заголовка и массива членов, заданных только их строкой идентификатора.

Теперь я хочу отобразить эти группы. Просто не так ли? Однако я не хочу, конечно, просто отображать идентификаторы участников, а полную информацию о пользователях групп (например, их имена ...).

Итак, у меня, конечно, есть служба для получения всех групп, а другая - для получения пользователя по его идентификатору.

В React, поскольку я не использую rxjs, у меня не возникло бы никаких проблем; async / ждет, и Promise.all сделает свое дело.

Однако здесь возникают некоторые проблемы при попытке получить полную информацию (вызов двух служб) перед ее отображением, а именно: 1. Я хочу получить группы 2. повторить это 3. Итерировать на членов группы 4. наконец, для каждого члена получить свой идентификатор. Поэтому каждая группа может иметь, например, массив groupcompleteusers, который я буду заполнять каждый раз, когда получаю информацию о пользователях из идентификатора ...

Итак, я попробовал следующее:
- сначала я попытался поиграть с async / awaits, Promises, но поскольку я звоню в службы, возвращающие Observables, я немного растерялся.
- тогда я попытался иметь вложенные подписки. Тем не менее, я совершенно не могу написать это правильно, так как я перебираю не только группы, но и group.members (который не существует во время вложенной подписки, поскольку группа в это время является Observable. ..)

Итак, с угловой 7 / rxjs 6 я попробовал следующее:

getGroups(){
this.groupsService.getGroups().pipe(
  flatMap(group => 
    {
      for(let member of group.members){
        this.userService.getUser(member);
      }
    }
    )
).subscribe(u => this.groups = u)


}

Конечно, это не работает, тем более что group.members не существует в то время ...

Так что я немного застрял.

Может, у кого-то есть подсказка?

Спасибо!

1 Ответ

0 голосов
/ 18 ноября 2018

Функция flatMap ожидает, что вы вернете Observable, поэтому вы можете сделать что-то вроде:

import { forkJoin } from 'rxjs';

getGroups(){
  this.groupsService.getGroups().pipe(
    flatMap((groups: any[]) => {
      let members = groups.map(grp => grp.members)
                          .reduce((res, arr) => res.concat(arr), []);
                          .map(member => this.userService.getUser(member))
      return forkJoin(members);
    })
  )
).subscribe(u => this.groups = u)

Здесь мы используем map в массиве, чтобы преобразовать его из массива members в массив Observable. Затем мы используем forkJoin, чтобы объединить массив Observable в один Observable и вернуть его в flatMap

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...