Как переключить карту потока из 3 Observables - PullRequest
0 голосов
/ 08 апреля 2020

Я должен объединить 3 потока Observable в один. Я использую Angular и Firebase, вот как это должно работать ...

Шаг 1: Я отправляю запрос в Firebase и получаю array. Я буду использовать id из свойства Speci c, чтобы запросить что-то еще для Шаг 2 .

Шаг 2: Я использую ID из Шаг 1 , чтобы получить данные из другой коллекции, для этого я получу еще один array. В этом массиве у меня есть еще один ID , который мне нужен для Шаг 3 .

Шаг 3: Мне нужно получить объект из базы данных, используя Идентификатор , предоставленный на шаге 2.

Для того, чтобы это работало, я использую switchMap(), но проблема в том, что я получаю VOID как результат метода.

Помогите пожалуйста!

ОБНОВЛЕНИЕ: Я изменил оригинальный код. С этим я могу видеть console.log, но когда я подписываюсь, я ничего не получаю.

getPanic() {
  this.panicInfo = this.panicService.getPanic(this.checkID)
    .pipe(
      switchMap(panicSnaps => {
        const requests = panicSnaps.map(panicSnap => {
          const panicObj = {id: panicSnap.payload.doc.id, ...panicSnap.payload.doc.data() as any};
          return this.panicService.getActions(panicObj.id)
            .pipe(
              tap({ complete: () => console.log('completed')}),
              map(data => {
                panicObj.actions = data;
                console.log(panicObj);
                return panicObj;
              })
            );
        });
        return forkJoin(requests);
      }),
    )
    .subscribe();
}

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

проверить этот код:

getPanic() {
  this.panicService.getPanic(this.checkID)
    .pipe(
      switchMap((panicData: any[]) => forkJoin(
        ...panicData.map(snaps => {
          const panicObj = { ...snaps.payload.doc.data() };

          return this.panicService.getActions(panicObj.id).pipe(
            switchMap((actionSnaps: any[]) => forkJoin(
              ...actionSnaps.map(actionSnap => {
                const actionsObj: any = { ...actionSnap };

                return this.userService.getUser(actionsObj.executor).pipe(
                  map(userSNAP => ({ ...panicObj, ...actionsObj, ...userSNAP })),
                );
              }),
            )),
          );
        }),
      )),
    )
    .subscribe(data => {
      // The panicInfo is of type 'Panic' but I get a TS Lint error that says:
      // Type 'void[]' is missing the following properties from type 'Panic': id, checkId, city, geolocation, and 10 more
      this.panicInfo = data;
    });

мой пример на stackblitz

Я не знаю, какие данные вы получаете в запросах.

0 голосов
/ 09 апреля 2020

это хорошая идея разбить потоки, чтобы вы могли видеть, где вы идете не так.

getActionUsers(actionSnaps) {
  const actions = actionSnaps.map(actionSnap => {
    const actionsObj: PanicActions = {...actionSnap};
    // need to return inside map
    return this.userService.getUser(actionsObj.executor).pipe( 
      map(userSNAP => ({...actionsObj, ...userSNAP})) // combine only action and user here
    );
  });
  // need to combine and return (deal with empty)
  return actions.length ? combineLatest(...actions) : of([]);
}

getPanicActions(panicData) {
  const panic = panicData.map(snaps => {
    const panicObj: Panic = {...snaps.payload.doc.data()};
    return this.panicService.getActions(panicObj.id).pipe(
      switchMap(actionSnaps => this.getActionUsers(actionSnaps).pipe(
        map(res => ({...panicObj, ...res})) // add panicObj here
      ))
    );
  });
  // forkJoin only works on observables that complete, use combineLatest when they don't, also need to deal with empty
  return panic.length ? combineLatest(...panic) : of([]);
}


getPanic() {
  this.panicService.getPanic(this.checkID).pipe( 
    switchMap(panicData => this.getPanicActions(panicData))
  ).subscribe(data => {
    // The panicInfo is of type 'Panic' but I get a TS Lint error that says:
    // Type 'void[]' is missing the following properties from type 'Panic': id, checkId, city, geolocation, and 10 more
    this.panicInfo = data;
  });
}
...