I got a service method working that would get all of the items from a collection, and merge in user data from a different user collection so that it could easily be displayed on the front end.
I tried to add a third layer of observables to pull and merge another set of data, but it's now just returning observable data to the front end.
This is the call that is working with adding in the users.
getEventList(pid: string, sid: string) {
return this.afs.collection(this.partyCollectionPath + pid + this.sessionCollectionPath + sid + this.eventCollectionPath,
ref => ref.orderBy('timestamp', 'desc')).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as events_list;
const id = a.payload.doc.id;
return this.afs.doc("users/" + data.uid).snapshotChanges().pipe(map(a => {
const useData = a.payload.data() as User
return { id, ...data, user: { ...useData}}
}))
})
}
),
mergeMap(obs => combineLatest(obs))
)
}
And this is the code where I tried to add a third layer in to look at the inventoryID from the event. The console.log('iData', iData) isn't actually even hitting, and doesn't even appear in my console when I subscribe to this method so my final return isn't coming through. What did I miss here, can you not add another layer to this?
getEventList(pid: string, sid: string) {
return this.afs.collection(this.partyCollectionPath + pid + this.sessionCollectionPath + sid + this.eventCollectionPath,
ref => ref.orderBy('timestamp', 'desc')).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as events_list;
const id = a.payload.doc.id;
return this.afs.doc("users/" + data.uid).snapshotChanges().pipe(map(a => {
const useData = a.payload.data() as User
return this.afs.doc(this.partyCollectionPath + pid + "/Party-Inventory/" + data.inventoryId).snapshotChanges().pipe(map(b => {
const iData = b.payload.data() as inventory_list
console.log('iData', iData)
return { id, ...data, user: { ...useData }, inventoryData: { ...iData } }
}))
}))
})
}
),
mergeMap(obs => combineLatest(obs))
)
}
Update This is what I got working for this scenario. In the end, I only wanted to run the combineLatest once, so the second mergemap from the answer was absolutely correct, I just needed to move my second internal observable call and final return value in there, which is then picked up by the outer observable mergeMap and combineLatest.
getEventList(pid: string, sid: string) {
return this.afs.collection(this.partyCollectionPath + pid + this.sessionCollectionPath + sid + this.eventCollectionPath,
ref => ref.orderBy('timestamp', 'desc')).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as events_list;
const id = a.payload.doc.id;
return this.afs.doc("users/" + data.uid).snapshotChanges().pipe(map(a => {
const useData = a.payload.data() as User
return { ...useData }
}), mergeMap( a => {
return this.afs.doc(this.partyCollectionPath + pid + "/Party-Inventory/" + data.typeId).snapshotChanges().pipe(map(b => {
const iData = b.payload.data() as inventory_list
return { id, ...data, user: { ...a }, inventoryData: { ...iData } }
}))
}))
})
}
),
mergeMap(obs => combineLatest(obs))
)
}