RxJS Observables does not display data on subscribe or async

≯℡__Kan透↙ 提交于 2019-12-13 03:31:24

问题


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.


回答1:


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



回答2:


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;




回答3:


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


来源:https://stackoverflow.com/questions/49398981/rxjs-observables-does-not-display-data-on-subscribe-or-async

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