In the observable pipeline below colWithIds$
gives me an observable of a firestore collection (a single array of objects) which I'll refer to as the parent documents. For each of those documents I use flatMap
to make a single call for an associated document, which I'll call the child documents. I then store the parent and child docs on local variables:
this.db.colWithIds$('parentCollection')
.pipe(
tap(parentDocs => this.parentDocs = _.keyBy(parentDocs, '_id')),
flatMap(parentDocs => combineLatest(parentDocs.map(doc => this.db.doc(`childCollection/${doc.childId}`).get()))),
map(snaps => convertSnaps(snaps)),
tap(childDocs => this.childDocs = _.keyBy(childDocs, '_id'))
).subscribe()
The problems with this approach:
I'm looking for a way that I can wait until all values have been resolved and return a single object in the following form:
{
parentDocs: [{}, {}, ...], // the documents
childDocs: [{}, {}, ...], // the documents
}
I'm open to other solutions to the problems listed above. Thanks in advance.
Is this what you are looking for? This way you don't query the database twice for parents.
this.db.colWithIds$(`parentCollection`).pipe(
map(parentDocs => _.keyBy(parentDocs, '_id')),
flatMap(parentDocs => combineLatest(_.map(parentDocs, parent => this.db.docWithId$(`childDocs/${parent.childId}`))).pipe(
map(childDocs => _.keyBy(childDocs, '_id')),
map(childDocs => ({parentDocs, childDocs}))
))
);