kkdeveloper7
kkdeveloper7

Reputation: 565

RxJS Output an array of Subscription from multiple mergeMap

I was wondering if its possible to output an array ob observable after making multiple mergeMap calls

Here is an example f what i would like to get back

 this.kbSvc.create(kb).pipe(
            map(dbKb => kb = dbKb),
            mergeMap(() => this.goSvc.create(kb.id, "Build Market Share")),
            mergeMap(go => this.marketSvc.create(kb.id, (<GrowthOpportunity>go).id, "Market Segment - TBD")),
            mergeMap(ms => this.companySvc.create({ id: kb.id, msId: (<MarketSegment>ms).id }, "Company Type - TBD")),
        ).subscribe(([goSvc Result, marketSvc Result, companySvc Result]) => // //);

All of the calls above depend on each other there for i can not use forkJoin. In other words my previous observable must complete before invoking new one.

I am trying to avoid multiple map calls avfer each mergeMap and storing my resulted value from each observable.

Thank you!

Upvotes: 0

Views: 470

Answers (2)

emkay
emkay

Reputation: 807

Operators I have come across so far doesn't maintain the state of the values received or emitted. Like the water stream, they just let the data flow after modifying the way they wish to.

One solution can be through nested pipe operators so you still have access to data from your previous operators.

Let's define all your observable under function for clarity.

goFunc(id) {
  return this.goSvc.create(id, "Build Market Share");
}

marketFunc(id, goData) {
  return this.marketSvc.create(id, (<GrowthOpportunity>goData).id, "Market Segment - TBD");
}

companyFunc(id, msData) {
  return this.companySvc.create({ id: id, msId: (<MarketSegment>msData).id }, "Company Type - TBD");
}

Here is the function for nested piping,

 someFunc() {

 this.kbSvc.create(kb).pipe(
  mergeMap(kb => this.goFunc(kb).pipe(
    mergeMap(goData => this.marketFunc(kb,goData).pipe(
      mergeMap(msData => this.companyFunc(kb,msData).pipe(
        map((companyData) => [goData,msData,companyData])
      )),
    ))
  ))
 ).subscribe(data => {
  //data will have [goData,msData,companyData]
  console.log(data);
 });

}

This should give the expected output.

Upvotes: 1

user2216584
user2216584

Reputation: 5602

One of the options could be to use combineLatest like this -

this.kbSvc
        .create(kb)
        .pipe(
                map(dbKb => kb = dbKb),
                mergeMap(() => this.goSvc.create(kb.id, "Build Market Share")),
                mergeMap(go => {

                  return combinedLatest(of(go), this.marketSvc.create(kb.id, (<GrowthOpportunity>go).id, "Market Segment - TBD"));

                }),
                mergeMap(([goSvcResult, marketSvcResult]) => {
                  return combinedLatest(of([goSvcResult, marketSvcResult]), this.companySvc.create({ id: kb.id, msId: (<MarketSegment>marketSvcResult).id }, "Company Type - TBD"));
                })

        ).subscribe(([[goSvc Result, marketSvc Result], companySvc Result]) => // //);

Notice the subscribe callback input. Although it is not exactly what you expect still it is almost the same.

Upvotes: 0

Related Questions