value from Observable within Observable using angularfire2 firestore

我是研究僧i 提交于 2019-12-24 14:40:36

问题


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?


回答1:


So your problem is that the maps 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):

this.lstCategories = this.availableCategories$.mergeMap(data => {
  const observables = data.map((rec: CategoryId) => {
    if (rec.hasSubCat) {
      return this.httpDataService... // Observable
    } else {
      const arr: any = {};
      ...
      return Observable.of(arr); // Observable
    }
  }

  return Observable.forkJoin(observables);
});

Also notice that I had to use this.availableCategories$.mergeMap() because mergeMap will subscribe to the forkJoin Observable and emit its result.



来源:https://stackoverflow.com/questions/49391733/value-from-observable-within-observable-using-angularfire2-firestore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!