1

I need to call a subscribe method within a subscribe method.

In the first subscribe method, it returns me a deviceid which is subsequently used in the second subscribe method.

result=[];
idArray=[2,4];

this.subscription =
    this.quoteService.get(this.quoteid) //first api call
     .subscribe((quote: Quote) => {   
       this.deviceid = quote["deviceid"]; 
       this.faultService.get(this.deviceid) //second api call
        .pipe(first())
        .subscribe((faultGroup: FaultGroup[]) => {
        faultGroup.forEach(({ faults }) => {
          //execute logic for 2nd subscription
          if (faults) {
            faults
              .filter(
                ({ id }) => this.idArray.indexOf(id) > -1,
              )
              .forEach(fault => this.result.push(fault.name));
          }
          //end of logic
        });
      });
    subscription.unsubscribe();
  }
});

Can someone teach me how to use flatMap/switchMap to avoid using a nested subscribe? Appreciate your help!

1
  • What is first()? a synchronous method ? Commented Dec 6, 2018 at 2:14

1 Answer 1

3

Here your requirement is to return then result from the second API, it's just that to call the second API, you need the result from the first. For this, switchMap() suites you best. Use it like explained in the code.

this.subOb = this.quoteService.get(this.quoteid) //first api call
    .pipe(switchMap((quote: Quote) => {
          // result of first API call here
        this.deviceid = quote["deviceid"];
          // you need to return the second observable from inside the switcMap
          // and this will only be executed after the first Observable(first API call) is finished
        return this.faultService.get(this.deviceid) //second api call
          // need some mode logic after second API call is done? call first()?
          // map the result with a pipe
            .pipe(map(secondData) => { 
                  // If you aren't manipulating the data 
                  // to be returned, then use tap() instead of map().
                return data;
            })

    }))
        .subscribe((data) => {
            // only one subscription is required.
            // this will have data from second API call
        })

Use the ngOnDestroy() hook to unsubcribe() for the Subscriptions. I see that you are assigning the subscription to a variable and probably uing the same to unsubscribe. If your Observable emits multiple time(which I think it doesn't) then during the first emission when it comes to subscribe(), the "subscription" variable will be undeifned.

ngOnDestroy() {
    if (this.subOb) {
        this.subOb.unsubscribe();
    }
}

See a sample example here: https://stackblitz.com/edit/swicthmap?file=src%2Fapp%2Fapp.component.ts

It contains two implementations of switch maps, analyze both and use whatever suites you.

Sign up to request clarification or add additional context in comments.

7 Comments

hi xyz thanks for your help! May I know if its possible to skip the tap and map part and go straight to the second subscribe? e.g. return this.faultService.get(this.deviceid).subscribe(etc.)
@iBlehhz If you want to execute any logic after the second request then you have to use map or tap. And No we are not doing a subscribe on the second API call, switchMap expects an Observable, not a Subscription as a return. We are doing subscription only on the outer API call.
@iBlehhz: what does the method first() do?
@iBlehhz: See the link added in the example
hey thanks so much!! I figured it out with your help. can't thank you enough you're a life saver :DDD
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.