RxJS Observables does not display data on subscrib

2019-08-19 15:52发布

I am trying to get all the data from firestore - collection and subcollection into an observable form of array and display it with async pipe.

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$.mergeMap(data => {
  const observables = data.map((rec: CategoryId) => {
    if (rec.hasSubCat) {
      return this.httpDataService.getSubCategory(rec.cId).snapshotChanges().map(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 Observable.of(arr);
        });
      });
    }else {
      const arr: any = {};
      arr.id = rec.id;
      arr.itemName = rec.categoryName;
      arr.category = 'All';
      return Observable.of(arr);
    }
  });
  return Observable.forkJoin(observables);
});

and I've used <pre>{{lstCategories | async | json}}</pre> to display the data, but it is always null.

When I console.log(observables) before forkJoin I get (9) [ScalarObservable, Observable, Observable, ScalarObservable, ScalarObservable, ScalarObservable, ScalarObservable, ScalarObservable, Observable] out of which 3 of them which are Observable are subcategories and 6 of them which are ScalarObservable are main categories.

In spite of this data, the lstCategories doesn't get updated via async.

I've also tried to subscribe to lstCategories like

this.lstCategories.subscribe(data => {
     console.log(data);
});

but the above log never happens which means it is not getting subscribed. My knowledge on rxjs is very weak. Hope to find some help here.

3条回答
看我几分像从前
2楼-- · 2019-08-19 16:16

When you use map, you transform the response of a request. You needn't return an Observalbe

this.httpDataService.getSubCategory(rec.cId).snapshotChanges().map(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  //<--simply return arr
          // return Observable.of(arr); <--I think it's WORNG
        });
查看更多
做自己的国王
3楼-- · 2019-08-19 16:21

Try this way

this.lstCategories = this.availableCategoriesCollection.snapshotChanges().map(changes => {
      return changes.map(a => {
        const data = a.payload.doc.data() as Category;
        if(data.hasSubCat){
          const signupId = a.payload.doc.id;
          return this.httpDataService.getSubCategory(signupId).snapshotChanges().map(actions => {
            return actions.map(d => {
              return d;
            });
          }).map(signup => {
            return signup.map(md => {
              const arr: any = {};
              arr.id = md.payload.doc.id;
              arr.itemName = (md.payload.doc.data() as Category).categoryName;
              arr.category = data.categoryName;
              return arr;
            });
          });
        }else {
          const arr: any = {};
          arr.id = a.payload.doc.id;
          arr.itemName = data.categoryName;
          arr.category = 'All';
          return Observable.of(arr);
        }
      });
    }).flatMap(records => Observable.combineLatest(records)).map(data => {
      return [].concat(...data).map(d => {
        return d;
      })
    });
查看更多
Luminary・发光体
4楼-- · 2019-08-19 16:37

It seems that you are returning Observable of Observable of some array at following code block

map(d => 
...
arr.id = r.payload.doc.id;
arr.itemName = (r.payload.doc.data() as Category).categoryName;
arr.category = rec.categoryName;
return Observable.of(arr);
...

This block is already inside a map function of an Observable. When you return another Observable your whole return object looks like Observable<Observable<any[]>> Just change return line to return arr;

查看更多
登录 后发表回答