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 函数看来,aAreas
和 bAreas
是数组,但 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;
}
我有一个函数,它 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 函数看来,aAreas
和 bAreas
是数组,但 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;
}