I am trying to query a sub-collection if exists while querying for document
from collection
. My first query returns/maps
data properly but when I try to query the subcollection
it will be stored as observable
within the Observable<data>
. Below is what I have/tried so far.
component.ts
availableCategoriesCollection: AngularFirestoreCollection<Category>;
availableCategories$: Observable<CategoryId[]>;
lstCategories: Observable<any>;
this.availableCategoriesCollection = this.httpDataService.getAllCategories();
this.availableCategories$ = this.availableCategoriesCollection.snapshotChanges().map(data => {
return data.map(record => {
const rec = record.payload.doc.data() as Category;
const cId = record.payload.doc.id;
return {cId, ...rec};
});
});
this.lstCategories = this.availableCategories$.map(data => {
return data.map((rec: CategoryId) => {
//if a category has subcategory then query the document again for subcollection
if (rec.hasSubCat) {
return this.httpDataService.getSubCategory(rec.cId).snapshotChanges().concatMap(d => {
return d.map(r => {
const arr: any = {};
arr.id = r.payload.doc.id;
arr.itemName = (r.payload.doc.data() as Category).categoryName;
arr.category = rec.categoryName;
return arr;
});
});
}else {
const arr: any = {};
arr.id = rec.id;
arr.itemName = rec.categoryName;
arr.category = 'All';
return arr;
}
});
});
When I look into the lstCategories
value, the documents that have subcollection
will be returned as Observable
and the ones which don't have subcollection
returns proper data
with id
,itemName
and category
. Something like below:
(9) [{…}, Observable, Observable, {…}, {…}, {…}, {…}, {…}, Observable]
How can I properly subscribe to the sub-query
? What am I missing here?
So your problem is that the
map
s callback sometimes returns a plain object and sometimes returns an Observable. I guess you still want to emit an array of objects (including those inside the inner Observables) instead of emitting items one by one.I think the easiest way to do this is using
forkJoin
and always returning an Observable (even when the result could be a plain object):Also notice that I had to use
this.availableCategories$.mergeMap()
becausemergeMap
will subscribe to theforkJoin
Observable and emit its result.