Home > Enterprise >  How to chain subscriptions and return a single observable
How to chain subscriptions and return a single observable

Time:05-05

i m trying to chain 3 subscriptions in a service and return an observable so all the components can subscribe single observable. When i console.log "_campaigns" its always empty. I believe some sync. problem there. the I m new to Rx.js, any ideas how could i achieve this ?

public publicListSuccessSub$ = new Subject<SlotsPromoCampaign[]>();
  public publicListErrorSub$ = new Subject<any>();

  public userListSuccessSub$ = new Subject<SlotsPromoCampaign[]>();
  public userListErrorSub$ = new Subject<any>();

  public cmsListSuccessSub$ = new Subject<CmsPromoCampaign[]>();
  public cmsListErrorSub$ = new Subject<any>();

    public loadCampaigns() {
        this.cmsListSuccessSub$.subscribe((items: CmsPromoCampaign[]) => {
          this._cmsCampaigns = items;
          this.reloadCampaigns(this.userService.loggedIn);
        });
    
        this.userListSuccessSub$.subscribe((items: SlotsPromoCampaign[]) => {
          this.appendCampaigns(items);
        });
    
        this.publicListSuccessSub$.subscribe((items: SlotsPromoCampaign[]) => {
          this.appendCampaigns(items);
        });
    
        this.getCmsList();
          console.log(this._campaigns)
        return of(this._campaigns);
      }

    private appendCampaigns(items: SlotsPromoCampaign[]): void {
        items.forEach((item: SlotsPromoCampaign) => {
          if (this._campaigns && !this._campaigns.find(c => c.id === item.id)) {
            this.updateCmsInfo(item);
            item.setVisibility(this.userService.loggedIn);
            this._campaigns.push(item);
          }
        });
      }

what i tried

 return forkJoin([this.cmsListSuccessSub$,this.userListSuccessSub$,this.publicListSuccessSub$
]).pipe(map(arr=> {
  this._cmsCampaigns = arr[0];
  this.reloadCampaigns(this.userService.loggedIn);
  this.appendCampaigns(arr[1]);
  this.appendCampaigns(arr[2])
}));

also tried with mergeAll. its triggered but i dont know how to use this.appendCampaigns(items) there

of(this.cmsListSuccessSub$,this.userListSuccessSub$,this.publicListSuccessSub$)
      .pipe(
        mergeAll(),
      )
      .subscribe(item => {
        console.log(item)
      })
    this.getCmsList();

CodePudding user response:

If those are single shot streams (like http requests) then forkJoin and you are good to go

forkJoin([
 this.cmsListSuccessSub$,this.userListSuccessSub$,this.publicListSuccessSub$
]).pipe(map(arr=>([...arr[0],...arr[1],...arr[2])).subscribe((allItems)=>this._cmsCampaigns = items)

If those are continous, use mergeAll

CodePudding user response:

forkJoin only emits once all observables complete - but those Subject observables won't complete

There isn't enough info here to be sure, but combineLatest is worth a look

  • Related