Chain 3 or more dependent observables












2














I know this question has been asked before here. But the solution accepted is not working for me or I am not able to understand it well.



I am using ng-7
I have simple use case:



I have 2 APIs, 2nd is dependent on 1st's response.
I subscribe to result of 1st API and then using pipe subscribe to 2nd API result.



My code looks like below;



this._SomeService
.addUserToDb(payload)
.pipe(
map(res => res),
mergeMap(db1Response =>
this._SomeService.addUserToDb2(db1Response
)
),
catchError(errodb1 => {

return Observable.throw(new
Error(errorSso));
})
)
.subscribe(
resDb2 => {
// Here I get response of addUserToDb2
},
errDb2 => {


}
)


Now before subscribing to second API response I want to subscribe to another observable say:



this._tokenService.getToken.pipe(



)



And Want to use it's response in service 2.
Such that:



API1 => token => API2



Please suggest how to implement.



UPDATE:



I tried to implement, below is my implementation:



  this._service.addUserToDB1(payload).pipe(
map(resp => this.resDB1 = resp) // Adding to global variable because I need this response while subscribing to DB2 service.
,mergeMap(resdb1=>this._tokenService.getToken.pipe(
mergeMap(token => this._service.addUserToDb2(
this.resDB1,
this.organizationId,
this.practitionerId,
token
),
catchError(errorToken => {

return Observable.throw(new Error(errorToken));
})),
)
),
catchError(errordb1 => {

return Observable.throw(new Error(errordb1));
})

).subscribe (
resdb2Response =>
{

},
errdb2 => {

}
)


Can someone validate if above implementation is fine or suggest right way?










share|improve this question





























    2














    I know this question has been asked before here. But the solution accepted is not working for me or I am not able to understand it well.



    I am using ng-7
    I have simple use case:



    I have 2 APIs, 2nd is dependent on 1st's response.
    I subscribe to result of 1st API and then using pipe subscribe to 2nd API result.



    My code looks like below;



    this._SomeService
    .addUserToDb(payload)
    .pipe(
    map(res => res),
    mergeMap(db1Response =>
    this._SomeService.addUserToDb2(db1Response
    )
    ),
    catchError(errodb1 => {

    return Observable.throw(new
    Error(errorSso));
    })
    )
    .subscribe(
    resDb2 => {
    // Here I get response of addUserToDb2
    },
    errDb2 => {


    }
    )


    Now before subscribing to second API response I want to subscribe to another observable say:



    this._tokenService.getToken.pipe(



    )



    And Want to use it's response in service 2.
    Such that:



    API1 => token => API2



    Please suggest how to implement.



    UPDATE:



    I tried to implement, below is my implementation:



      this._service.addUserToDB1(payload).pipe(
    map(resp => this.resDB1 = resp) // Adding to global variable because I need this response while subscribing to DB2 service.
    ,mergeMap(resdb1=>this._tokenService.getToken.pipe(
    mergeMap(token => this._service.addUserToDb2(
    this.resDB1,
    this.organizationId,
    this.practitionerId,
    token
    ),
    catchError(errorToken => {

    return Observable.throw(new Error(errorToken));
    })),
    )
    ),
    catchError(errordb1 => {

    return Observable.throw(new Error(errordb1));
    })

    ).subscribe (
    resdb2Response =>
    {

    },
    errdb2 => {

    }
    )


    Can someone validate if above implementation is fine or suggest right way?










    share|improve this question



























      2












      2








      2







      I know this question has been asked before here. But the solution accepted is not working for me or I am not able to understand it well.



      I am using ng-7
      I have simple use case:



      I have 2 APIs, 2nd is dependent on 1st's response.
      I subscribe to result of 1st API and then using pipe subscribe to 2nd API result.



      My code looks like below;



      this._SomeService
      .addUserToDb(payload)
      .pipe(
      map(res => res),
      mergeMap(db1Response =>
      this._SomeService.addUserToDb2(db1Response
      )
      ),
      catchError(errodb1 => {

      return Observable.throw(new
      Error(errorSso));
      })
      )
      .subscribe(
      resDb2 => {
      // Here I get response of addUserToDb2
      },
      errDb2 => {


      }
      )


      Now before subscribing to second API response I want to subscribe to another observable say:



      this._tokenService.getToken.pipe(



      )



      And Want to use it's response in service 2.
      Such that:



      API1 => token => API2



      Please suggest how to implement.



      UPDATE:



      I tried to implement, below is my implementation:



        this._service.addUserToDB1(payload).pipe(
      map(resp => this.resDB1 = resp) // Adding to global variable because I need this response while subscribing to DB2 service.
      ,mergeMap(resdb1=>this._tokenService.getToken.pipe(
      mergeMap(token => this._service.addUserToDb2(
      this.resDB1,
      this.organizationId,
      this.practitionerId,
      token
      ),
      catchError(errorToken => {

      return Observable.throw(new Error(errorToken));
      })),
      )
      ),
      catchError(errordb1 => {

      return Observable.throw(new Error(errordb1));
      })

      ).subscribe (
      resdb2Response =>
      {

      },
      errdb2 => {

      }
      )


      Can someone validate if above implementation is fine or suggest right way?










      share|improve this question















      I know this question has been asked before here. But the solution accepted is not working for me or I am not able to understand it well.



      I am using ng-7
      I have simple use case:



      I have 2 APIs, 2nd is dependent on 1st's response.
      I subscribe to result of 1st API and then using pipe subscribe to 2nd API result.



      My code looks like below;



      this._SomeService
      .addUserToDb(payload)
      .pipe(
      map(res => res),
      mergeMap(db1Response =>
      this._SomeService.addUserToDb2(db1Response
      )
      ),
      catchError(errodb1 => {

      return Observable.throw(new
      Error(errorSso));
      })
      )
      .subscribe(
      resDb2 => {
      // Here I get response of addUserToDb2
      },
      errDb2 => {


      }
      )


      Now before subscribing to second API response I want to subscribe to another observable say:



      this._tokenService.getToken.pipe(



      )



      And Want to use it's response in service 2.
      Such that:



      API1 => token => API2



      Please suggest how to implement.



      UPDATE:



      I tried to implement, below is my implementation:



        this._service.addUserToDB1(payload).pipe(
      map(resp => this.resDB1 = resp) // Adding to global variable because I need this response while subscribing to DB2 service.
      ,mergeMap(resdb1=>this._tokenService.getToken.pipe(
      mergeMap(token => this._service.addUserToDb2(
      this.resDB1,
      this.organizationId,
      this.practitionerId,
      token
      ),
      catchError(errorToken => {

      return Observable.throw(new Error(errorToken));
      })),
      )
      ),
      catchError(errordb1 => {

      return Observable.throw(new Error(errordb1));
      })

      ).subscribe (
      resdb2Response =>
      {

      },
      errdb2 => {

      }
      )


      Can someone validate if above implementation is fine or suggest right way?







      observable rxjs6 angular7 rxjs-pipeable-operators






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 26 at 11:58

























      asked Nov 20 at 9:53









      Harsimer

      92131442




      92131442
























          1 Answer
          1






          active

          oldest

          votes


















          1





          +50









          mergeMap operator is fine here since Api requests emit 1 event and then complete, but to be precise please use switchMap or concatMap instead of mergeMap. Please have a look at this post about these operators as well, if you are interested. RxJs Mapping Operators: switchMap, mergeMap, concatMap



          As for your code block I would suggest something similar which is:



          this._service.addUserToDB1(payload).pipe(
          catchError(errordb1 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb1));
          }),
          tap(resp => this.resDB1 = resp),
          switchMap(resdb1 => this._tokenService.getToken),
          catchError(errorToken => {
          // do something with error if you want
          return Observable.throw(new Error(errorToken));
          }),
          switchMap(token => this._service.addUserToDb2(
          this.resDB1,
          this.organizationId,
          this.practitionerId,
          token
          )),
          catchError(errordb2 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb2));
          }),
          ).subscribe(
          resdb2Response => {

          },
          anyError => {
          // any of the errors will come here
          }
          )




          • tap() operator is like just do something and don't change anything to emitted event. Prefer tap over map when you just want to do something, instead of transforming emitted event.






          share|improve this answer





















          • Goga Koreli Thanks a lot for answering. I have one query, In 'anyerror' we will receive error from received from this._service.addUserToDb2? If yes then why we have cathError block for errordb2?
            – Harsimer
            Nov 28 at 9:48










          • @Simer You will receive error from this._service.addUserToDb2( but as well from this._service.addUserToDB1, so if you want to write logic no matter which error comes up this is the place. Thats why catchError(errordb2 => { is still there so that you can write specific logic on that error. If you don't want specific logic for that case you can remove that catchError block
            – Goga Koreli
            Nov 29 at 9:52












          • Ok thanks again! So which error we will receive in 'anyError => { // any of the errors will come here }'? Aren't we going to receive _service.addUserToDb2 errors there only?
            – Harsimer
            Nov 29 at 10:03










          • No not only 1 specific, but all of them: eitheir errordb1, errorToken or errordb2, because when the error happens you are not only consuming the error but also re-throwing it as seen for example in return Observable.throw(new Error(errordb1));. So inside subscribe as a second parameter we are passing onError(err) function which will be called by the runtime when the error is thrown inside Observable. So any of the errors thrown in the Observable will finally arrive here.
            – Goga Koreli
            Nov 29 at 12:31













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53390328%2fchain-3-or-more-dependent-observables%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1





          +50









          mergeMap operator is fine here since Api requests emit 1 event and then complete, but to be precise please use switchMap or concatMap instead of mergeMap. Please have a look at this post about these operators as well, if you are interested. RxJs Mapping Operators: switchMap, mergeMap, concatMap



          As for your code block I would suggest something similar which is:



          this._service.addUserToDB1(payload).pipe(
          catchError(errordb1 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb1));
          }),
          tap(resp => this.resDB1 = resp),
          switchMap(resdb1 => this._tokenService.getToken),
          catchError(errorToken => {
          // do something with error if you want
          return Observable.throw(new Error(errorToken));
          }),
          switchMap(token => this._service.addUserToDb2(
          this.resDB1,
          this.organizationId,
          this.practitionerId,
          token
          )),
          catchError(errordb2 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb2));
          }),
          ).subscribe(
          resdb2Response => {

          },
          anyError => {
          // any of the errors will come here
          }
          )




          • tap() operator is like just do something and don't change anything to emitted event. Prefer tap over map when you just want to do something, instead of transforming emitted event.






          share|improve this answer





















          • Goga Koreli Thanks a lot for answering. I have one query, In 'anyerror' we will receive error from received from this._service.addUserToDb2? If yes then why we have cathError block for errordb2?
            – Harsimer
            Nov 28 at 9:48










          • @Simer You will receive error from this._service.addUserToDb2( but as well from this._service.addUserToDB1, so if you want to write logic no matter which error comes up this is the place. Thats why catchError(errordb2 => { is still there so that you can write specific logic on that error. If you don't want specific logic for that case you can remove that catchError block
            – Goga Koreli
            Nov 29 at 9:52












          • Ok thanks again! So which error we will receive in 'anyError => { // any of the errors will come here }'? Aren't we going to receive _service.addUserToDb2 errors there only?
            – Harsimer
            Nov 29 at 10:03










          • No not only 1 specific, but all of them: eitheir errordb1, errorToken or errordb2, because when the error happens you are not only consuming the error but also re-throwing it as seen for example in return Observable.throw(new Error(errordb1));. So inside subscribe as a second parameter we are passing onError(err) function which will be called by the runtime when the error is thrown inside Observable. So any of the errors thrown in the Observable will finally arrive here.
            – Goga Koreli
            Nov 29 at 12:31


















          1





          +50









          mergeMap operator is fine here since Api requests emit 1 event and then complete, but to be precise please use switchMap or concatMap instead of mergeMap. Please have a look at this post about these operators as well, if you are interested. RxJs Mapping Operators: switchMap, mergeMap, concatMap



          As for your code block I would suggest something similar which is:



          this._service.addUserToDB1(payload).pipe(
          catchError(errordb1 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb1));
          }),
          tap(resp => this.resDB1 = resp),
          switchMap(resdb1 => this._tokenService.getToken),
          catchError(errorToken => {
          // do something with error if you want
          return Observable.throw(new Error(errorToken));
          }),
          switchMap(token => this._service.addUserToDb2(
          this.resDB1,
          this.organizationId,
          this.practitionerId,
          token
          )),
          catchError(errordb2 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb2));
          }),
          ).subscribe(
          resdb2Response => {

          },
          anyError => {
          // any of the errors will come here
          }
          )




          • tap() operator is like just do something and don't change anything to emitted event. Prefer tap over map when you just want to do something, instead of transforming emitted event.






          share|improve this answer





















          • Goga Koreli Thanks a lot for answering. I have one query, In 'anyerror' we will receive error from received from this._service.addUserToDb2? If yes then why we have cathError block for errordb2?
            – Harsimer
            Nov 28 at 9:48










          • @Simer You will receive error from this._service.addUserToDb2( but as well from this._service.addUserToDB1, so if you want to write logic no matter which error comes up this is the place. Thats why catchError(errordb2 => { is still there so that you can write specific logic on that error. If you don't want specific logic for that case you can remove that catchError block
            – Goga Koreli
            Nov 29 at 9:52












          • Ok thanks again! So which error we will receive in 'anyError => { // any of the errors will come here }'? Aren't we going to receive _service.addUserToDb2 errors there only?
            – Harsimer
            Nov 29 at 10:03










          • No not only 1 specific, but all of them: eitheir errordb1, errorToken or errordb2, because when the error happens you are not only consuming the error but also re-throwing it as seen for example in return Observable.throw(new Error(errordb1));. So inside subscribe as a second parameter we are passing onError(err) function which will be called by the runtime when the error is thrown inside Observable. So any of the errors thrown in the Observable will finally arrive here.
            – Goga Koreli
            Nov 29 at 12:31
















          1





          +50







          1





          +50



          1




          +50




          mergeMap operator is fine here since Api requests emit 1 event and then complete, but to be precise please use switchMap or concatMap instead of mergeMap. Please have a look at this post about these operators as well, if you are interested. RxJs Mapping Operators: switchMap, mergeMap, concatMap



          As for your code block I would suggest something similar which is:



          this._service.addUserToDB1(payload).pipe(
          catchError(errordb1 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb1));
          }),
          tap(resp => this.resDB1 = resp),
          switchMap(resdb1 => this._tokenService.getToken),
          catchError(errorToken => {
          // do something with error if you want
          return Observable.throw(new Error(errorToken));
          }),
          switchMap(token => this._service.addUserToDb2(
          this.resDB1,
          this.organizationId,
          this.practitionerId,
          token
          )),
          catchError(errordb2 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb2));
          }),
          ).subscribe(
          resdb2Response => {

          },
          anyError => {
          // any of the errors will come here
          }
          )




          • tap() operator is like just do something and don't change anything to emitted event. Prefer tap over map when you just want to do something, instead of transforming emitted event.






          share|improve this answer












          mergeMap operator is fine here since Api requests emit 1 event and then complete, but to be precise please use switchMap or concatMap instead of mergeMap. Please have a look at this post about these operators as well, if you are interested. RxJs Mapping Operators: switchMap, mergeMap, concatMap



          As for your code block I would suggest something similar which is:



          this._service.addUserToDB1(payload).pipe(
          catchError(errordb1 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb1));
          }),
          tap(resp => this.resDB1 = resp),
          switchMap(resdb1 => this._tokenService.getToken),
          catchError(errorToken => {
          // do something with error if you want
          return Observable.throw(new Error(errorToken));
          }),
          switchMap(token => this._service.addUserToDb2(
          this.resDB1,
          this.organizationId,
          this.practitionerId,
          token
          )),
          catchError(errordb2 => {
          // do something with error if you want
          return Observable.throw(new Error(errordb2));
          }),
          ).subscribe(
          resdb2Response => {

          },
          anyError => {
          // any of the errors will come here
          }
          )




          • tap() operator is like just do something and don't change anything to emitted event. Prefer tap over map when you just want to do something, instead of transforming emitted event.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 27 at 8:18









          Goga Koreli

          27319




          27319












          • Goga Koreli Thanks a lot for answering. I have one query, In 'anyerror' we will receive error from received from this._service.addUserToDb2? If yes then why we have cathError block for errordb2?
            – Harsimer
            Nov 28 at 9:48










          • @Simer You will receive error from this._service.addUserToDb2( but as well from this._service.addUserToDB1, so if you want to write logic no matter which error comes up this is the place. Thats why catchError(errordb2 => { is still there so that you can write specific logic on that error. If you don't want specific logic for that case you can remove that catchError block
            – Goga Koreli
            Nov 29 at 9:52












          • Ok thanks again! So which error we will receive in 'anyError => { // any of the errors will come here }'? Aren't we going to receive _service.addUserToDb2 errors there only?
            – Harsimer
            Nov 29 at 10:03










          • No not only 1 specific, but all of them: eitheir errordb1, errorToken or errordb2, because when the error happens you are not only consuming the error but also re-throwing it as seen for example in return Observable.throw(new Error(errordb1));. So inside subscribe as a second parameter we are passing onError(err) function which will be called by the runtime when the error is thrown inside Observable. So any of the errors thrown in the Observable will finally arrive here.
            – Goga Koreli
            Nov 29 at 12:31




















          • Goga Koreli Thanks a lot for answering. I have one query, In 'anyerror' we will receive error from received from this._service.addUserToDb2? If yes then why we have cathError block for errordb2?
            – Harsimer
            Nov 28 at 9:48










          • @Simer You will receive error from this._service.addUserToDb2( but as well from this._service.addUserToDB1, so if you want to write logic no matter which error comes up this is the place. Thats why catchError(errordb2 => { is still there so that you can write specific logic on that error. If you don't want specific logic for that case you can remove that catchError block
            – Goga Koreli
            Nov 29 at 9:52












          • Ok thanks again! So which error we will receive in 'anyError => { // any of the errors will come here }'? Aren't we going to receive _service.addUserToDb2 errors there only?
            – Harsimer
            Nov 29 at 10:03










          • No not only 1 specific, but all of them: eitheir errordb1, errorToken or errordb2, because when the error happens you are not only consuming the error but also re-throwing it as seen for example in return Observable.throw(new Error(errordb1));. So inside subscribe as a second parameter we are passing onError(err) function which will be called by the runtime when the error is thrown inside Observable. So any of the errors thrown in the Observable will finally arrive here.
            – Goga Koreli
            Nov 29 at 12:31


















          Goga Koreli Thanks a lot for answering. I have one query, In 'anyerror' we will receive error from received from this._service.addUserToDb2? If yes then why we have cathError block for errordb2?
          – Harsimer
          Nov 28 at 9:48




          Goga Koreli Thanks a lot for answering. I have one query, In 'anyerror' we will receive error from received from this._service.addUserToDb2? If yes then why we have cathError block for errordb2?
          – Harsimer
          Nov 28 at 9:48












          @Simer You will receive error from this._service.addUserToDb2( but as well from this._service.addUserToDB1, so if you want to write logic no matter which error comes up this is the place. Thats why catchError(errordb2 => { is still there so that you can write specific logic on that error. If you don't want specific logic for that case you can remove that catchError block
          – Goga Koreli
          Nov 29 at 9:52






          @Simer You will receive error from this._service.addUserToDb2( but as well from this._service.addUserToDB1, so if you want to write logic no matter which error comes up this is the place. Thats why catchError(errordb2 => { is still there so that you can write specific logic on that error. If you don't want specific logic for that case you can remove that catchError block
          – Goga Koreli
          Nov 29 at 9:52














          Ok thanks again! So which error we will receive in 'anyError => { // any of the errors will come here }'? Aren't we going to receive _service.addUserToDb2 errors there only?
          – Harsimer
          Nov 29 at 10:03




          Ok thanks again! So which error we will receive in 'anyError => { // any of the errors will come here }'? Aren't we going to receive _service.addUserToDb2 errors there only?
          – Harsimer
          Nov 29 at 10:03












          No not only 1 specific, but all of them: eitheir errordb1, errorToken or errordb2, because when the error happens you are not only consuming the error but also re-throwing it as seen for example in return Observable.throw(new Error(errordb1));. So inside subscribe as a second parameter we are passing onError(err) function which will be called by the runtime when the error is thrown inside Observable. So any of the errors thrown in the Observable will finally arrive here.
          – Goga Koreli
          Nov 29 at 12:31






          No not only 1 specific, but all of them: eitheir errordb1, errorToken or errordb2, because when the error happens you are not only consuming the error but also re-throwing it as seen for example in return Observable.throw(new Error(errordb1));. So inside subscribe as a second parameter we are passing onError(err) function which will be called by the runtime when the error is thrown inside Observable. So any of the errors thrown in the Observable will finally arrive here.
          – Goga Koreli
          Nov 29 at 12:31




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53390328%2fchain-3-or-more-dependent-observables%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Create new schema in PostgreSQL using DBeaver

          Deepest pit of an array with Javascript: test on Codility

          Fotorealismo