I have a function which returns an observable of some firebase collections which I want to subscribe to. It works fine without the code in-between the commented area but if this is added the observable returns nothing. I've been over this code multiple times but can't figure out why it's failing. Any ideas?
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;
}
For anyone running into this issue here is the solution...
I needed to modify the nested combineLatest operators to accommodate the possibility of nested arrays with zero length.
array.length ? array : [of([])])
Here is the modified, now working code...
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;
}