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?
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.