RXJS 因嵌套 switchmap 而失败

RXJS failing with nested switchmap

我有一个函数,它 returns 我想订阅的一些 firebase 集合的可观察对象。它在注释区域之间没有代码的情况下工作正常,但如果添加了可观察的 returns 什么都没有。我已经多次检查这段代码,但无法弄清楚为什么它会失败。有什么想法吗?

 watchFilesPages (businessId, jobId) {
    console.log('watchFilePages called with');
    console.log(businessId);
    console.log(jobId);
    const filesCollection =
    this._firestore
    .collection('clients')
    .doc(businessId)
    .collection('jobs')
    .doc(jobId)
    .collection('uploadedDocuments');
    const pagesResult = filesCollection.snapshotChanges()
    .pipe(
      map(actions => actions.map(a => {
        const data = a.payload.doc.data();
        const id = a.payload.doc.id;
        return { id, ...data };
      })),
      switchMap((files: any[]) => {
        const pages$ = files.map((f) =>
          this._firestore
          .collection('clients')
          .doc(businessId)
          .collection('jobs')
          .doc(jobId)
          .collection('uploadedDocuments')
          .doc(f.id)
          .collection('pages')
          .snapshotChanges().pipe(
            map(actions => actions.map(a => {
              const data = a.payload.doc.data();
              const id = a.payload.doc.id;
              return { id, ...data };
            })),
            switchMap((pages: any[]) => {
              const aAreas$ = pages.map((p) =>
                this._firestore
                .collection('clients')
                .doc(businessId)
                .collection('jobs')
                .doc(jobId)
                .collection('uploadedDocuments')
                .doc(f.id)
                .collection('pages')
                .doc(p.id)
                .collection('aAreas', ref => {
                    return ref
                      .orderBy('dateModified', 'desc');
                  })
                .snapshotChanges().pipe(
                  map(actions => actions.map(a => {
                    const data = a.payload.doc.data();
                    const id = a.payload.doc.id;
                    return { id, ...data };
                  })),
                ),
              );
              const bAreas$ = pages.map((p) =>
                this._firestore
                .collection('clients')
                .doc(businessId)
                .collection('jobs')
                .doc(jobId)
                .collection('uploadedDocuments')
                .doc(f.id)
                .collection('pages')
                .doc(p.id)
                .collection('bAreas', ref => {
                    return ref
                      .orderBy('dateModified', 'desc');
                  })
                .snapshotChanges().pipe(
                  map(actions => actions.map(a => {
                    const data = a.payload.doc.data();
                    const id = a.payload.doc.id;
                    return { id, ...data };
                  })),
                  ///////////////////////////////// code causing problems start ///////
                  switchMap((bAreas: any[]) => {
                    const aa$ = bAreas.map((b) =>
                      this._firestore
                          .collection('clients')
                          .doc(businessId)
                          .collection('jobs')
                          .doc(jobId)
                          .collection('uploadedDocuments')
                          .doc(f.id)
                          .collection('pages')
                          .doc(p.id)
                          .collection('bAreas')
                          .doc(b.id)
                          .collection('aa')
                          .snapshotChanges().pipe(
                            map(actions => actions.map(a => {
                              const data = a.payload.doc.data();
                              const id = a.payload.doc.id;
                              return { id, ...data };
                            })),
                          ),
                    );
                    const bb$ = bAreas.map((d) =>
                      this._firestore
                          .collection('clients')
                          .doc(businessId)
                          .collection('jobs')
                          .doc(jobId)
                          .collection('uploadedDocuments')
                          .doc(f.id)
                          .collection('pages')
                          .doc(p.id)
                          .collection('bAreas')
                          .doc(d.id)
                          .collection('bb')
                          .snapshotChanges().pipe(
                            map(actions => actions.map(a => {
                              const data = a.payload.doc.data();
                              const id = a.payload.doc.id;
                              return { id, ...data };
                            })),
                          ),
                    );
                    // passing the products value down the chain
                    return combineLatest([of(bAreas), combineLatest(aa$), combineLatest(bb$)]);
                  }),
                  map(([bAreas, aa, bb]) =>
                    bAreas.map((d2, idx) => {
                      d2.aa = aa[idx];
                      d2.bb = bb[idx];
                      return d2;
                    }),
                  ),
                  ///////////////////////////////// code causing problems end ///////
                ),
              );
              // passing the products value down the chain
              return combineLatest([of(pages), combineLatest(aAreas$), combineLatest(bAreas$)]);
            }),
            map(([pages, aAreas, bAreas]) =>
              pages.map((p2, idx) => {
                p2.aAreas = aAreas[idx];
                p2.bAreas = bAreas[idx];
                return p2;
              }),
            ),
          ),
        );
        return combineLatest([of(files), combineLatest(pages$)]);
      }),
      map(([files, pages]) =>
        files.map((f2, idx) => {
          f2.pages = pages[idx];
          return f2;
        }),
      ),
    );
    console.log('pagesResult');
    console.log(pagesResult);
    return pagesResult;
  }

尝试重写:

return combineLatest([of(bAreas), combineLatest(aa$), combineLatest(bb$)]);

对此:

return combineLatest([of(bAreas), aa$, bb$]);

以及您有类似嵌套的其他行 combineLatest.

从 map 函数看来,aAreasbAreas 是数组,但 combineLatest 会将它们包装到另一个数组中,因此您将它们作为数组的数组获取。

不确定这是导致问题的原因,但这是一个很好的起点。

对于任何 运行 解决这个问题的人来说,这里是解决方案...

我需要修改嵌套的 combineLatest 运算符以适应零长度嵌套数组的可能性。

array.length ? array : [of([])])

这是修改后的、现在可以工作的代码...

watchFilesPages (businessId, jobId) {
    console.log('watchFilePages called with');
    console.log(businessId);
    console.log(jobId);
    const filesCollection =
    this._firestore
    .collection('clients')
    .doc(businessId)
    .collection('jobs')
    .doc(jobId)
    .collection('uploadedDocuments');
    const pagesResult = filesCollection.snapshotChanges()
    .pipe(
      map(actions => actions.map(a => {
        const data = a.payload.doc.data();
        const id = a.payload.doc.id;
        return { id, ...data };
      })),
      switchMap((files: any[]) => {
        const pages$ = files.map((f) =>
          this._firestore
          .collection('clients')
          .doc(businessId)
          .collection('jobs')
          .doc(jobId)
          .collection('uploadedDocuments')
          .doc(f.id)
          .collection('pages')
          .snapshotChanges().pipe(
            map(actions => actions.map(a => {
              const data = a.payload.doc.data();
              const id = a.payload.doc.id;
              return { id, ...data };
            })),
            switchMap((pages: any[]) => {
              const aAreas$ = pages.map((p) =>
                this._firestore
                .collection('clients')
                .doc(businessId)
                .collection('jobs')
                .doc(jobId)
                .collection('uploadedDocuments')
                .doc(f.id)
                .collection('pages')
                .doc(p.id)
                .collection('aAreas', ref => {
                    return ref
                      .orderBy('dateModified', 'desc');
                  })
                .snapshotChanges().pipe(
                  map(actions => actions.map(a => {
                    const data = a.payload.doc.data();
                    const id = a.payload.doc.id;
                    return { id, ...data };
                  })),
                ),
              );
              const bAreas$ = pages.map((p) =>
                this._firestore
                .collection('clients')
                .doc(businessId)
                .collection('jobs')
                .doc(jobId)
                .collection('uploadedDocuments')
                .doc(f.id)
                .collection('pages')
                .doc(p.id)
                .collection('bAreas', ref => {
                    return ref
                      .orderBy('dateModified', 'desc');
                  })
                .snapshotChanges().pipe(
                  map(actions => actions.map(a => {
                    const data = a.payload.doc.data();
                    const id = a.payload.doc.id;
                    return { id, ...data };
                  })),
                  ///////////////////////////////// code causing problems start ///////
                  switchMap((bAreas: any[]) => {
                    const aa$ = bAreas.map((b) =>
                      this._firestore
                          .collection('clients')
                          .doc(businessId)
                          .collection('jobs')
                          .doc(jobId)
                          .collection('uploadedDocuments')
                          .doc(f.id)
                          .collection('pages')
                          .doc(p.id)
                          .collection('bAreas')
                          .doc(b.id)
                          .collection('aa')
                          .snapshotChanges().pipe(
                            map(actions => actions.map(a => {
                              const data = a.payload.doc.data();
                              const id = a.payload.doc.id;
                              return { id, ...data };
                            })),
                          ),
                    );
                    const bb$ = bAreas.map((d) =>
                      this._firestore
                          .collection('clients')
                          .doc(businessId)
                          .collection('jobs')
                          .doc(jobId)
                          .collection('uploadedDocuments')
                          .doc(f.id)
                          .collection('pages')
                          .doc(p.id)
                          .collection('bAreas')
                          .doc(d.id)
                          .collection('bb')
                          .snapshotChanges().pipe(
                            map(actions => actions.map(a => {
                              const data = a.payload.doc.data();
                              const id = a.payload.doc.id;
                              return { id, ...data };
                            })),
                          ),
                    );
                    // passing the products value down the chain
                    return combineLatest([of(bAreas), combineLatest(aa$.length ? aa$ : [of([])])), combineLatest(bb$.length ? bb$ : [of([])]))]);
                  }),
                  map(([bAreas, aa, bb]) =>
                    bAreas.map((d2, idx) => {
                      d2.aa = aa[idx];
                      d2.bb = bb[idx];
                      return d2;
                    }),
                  ),
                  ///////////////////////////////// code causing problems end ///////
                ),
              );
              // passing the products value down the chain
              return combineLatest([of(pages), combineLatest(aAreas$.length ? aAreas$ : [of([])])), combineLatest(bAreas$.length ? bAreas$ : [of([])]))]);
            }),
            map(([pages, aAreas, bAreas]) =>
              pages.map((p2, idx) => {
                p2.aAreas = aAreas[idx];
                p2.bAreas = bAreas[idx];
                return p2;
              }),
            ),
          ),
        );
        return combineLatest([of(files), combineLatest(pages$.length ? pages$ : [of([])]))]);
      }),
      map(([files, pages]) =>
        files.map((f2, idx) => {
          f2.pages = pages[idx];
          return f2;
        }),
      ),
    );
    console.log('pagesResult');
    console.log(pagesResult);
    return pagesResult;
  }