Chain 3 or more dependent observables
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
add a comment |
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
add a comment |
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
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
observable rxjs6 angular7 rxjs-pipeable-operators
edited Nov 26 at 11:58
asked Nov 20 at 9:53
Harsimer
92131442
92131442
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
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 fromthis._service.addUserToDb2(
but as well fromthis._service.addUserToDB1
, so if you want to write logic no matter which error comes up this is the place. Thats whycatchError(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 thatcatchError
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 inreturn Observable.throw(new Error(errordb1));
. So inside subscribe as a second parameter we are passingonError(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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 fromthis._service.addUserToDb2(
but as well fromthis._service.addUserToDB1
, so if you want to write logic no matter which error comes up this is the place. Thats whycatchError(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 thatcatchError
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 inreturn Observable.throw(new Error(errordb1));
. So inside subscribe as a second parameter we are passingonError(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
add a comment |
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.
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 fromthis._service.addUserToDb2(
but as well fromthis._service.addUserToDB1
, so if you want to write logic no matter which error comes up this is the place. Thats whycatchError(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 thatcatchError
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 inreturn Observable.throw(new Error(errordb1));
. So inside subscribe as a second parameter we are passingonError(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
add a comment |
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.
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.
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 fromthis._service.addUserToDb2(
but as well fromthis._service.addUserToDB1
, so if you want to write logic no matter which error comes up this is the place. Thats whycatchError(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 thatcatchError
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 inreturn Observable.throw(new Error(errordb1));
. So inside subscribe as a second parameter we are passingonError(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
add a comment |
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 fromthis._service.addUserToDb2(
but as well fromthis._service.addUserToDB1
, so if you want to write logic no matter which error comes up this is the place. Thats whycatchError(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 thatcatchError
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 inreturn Observable.throw(new Error(errordb1));
. So inside subscribe as a second parameter we are passingonError(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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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