使用angularfire2 firestore从Observable中的Observable获取值

时间:2018-03-20 18:30:41

标签: angular firebase rxjs angular5 google-cloud-firestore

我在document查询collection时尝试查询子集合是否存在。我的第一次查询returns/maps数据正确,但当我尝试查询subcollection时,它会在observable内存储为Observable<data>。以下是我到目前为止所做的一切。

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;
    }
  });
});

当我查看lstCategories值时,包含subcollection的文档将返回Observable,而没有subcollection的文档将返回正确的data 1}} iditemNamecategory。如下所示:

  

(9)[{...},Observable,Observable,{...},{...},{...},{...},{...},Observable]

如何正确订阅sub-query?我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

所以你的问题是map的回调有时会返回一个普通的对象,有时会返回一个Observable。我猜你还想发射一个对象数组(包括内部Observables中的对象),而不是逐个发出项目。

我认为最简单的方法是使用forkJoin并始终返回一个Observable(即使结果可能是普通对象):

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);
});

另请注意,我必须使用this.availableCategories$.mergeMap(),因为mergeMap将订阅forkJoin Observable并发出其结果。