In Angular 7, I am trying to invoke two different API methods sequentially. If first one is successful then need to call second API method.
If first API response code is 500 internal server error then second API should not be invoked. Also I need to handle errors for each API calls.
I tried Promise, async and await approach but when I check in developer tools, could see second one is invoked even if first API does not return any response.
Can someone please help me to achieve this using concatmap or any other Angular approach.
public fetchandUpdate() {
this.isSuccess= false;
this.errorMessage = "";
this.displayMessage = false;
// First API call
this.myService.getUserDetails(this.userid)
.subscribe(
(response) => {
console.log('response received')
this.userdetails= response;
},
(error) => {
console.error('error caught in fetching user details')
this.errorMessage = error;
this.isSuccess= false;
}
)
// Need to call this only if first API's response http status code is not 500
if(firstAPIresponse.statuscode != 500)
{
this.myService.updateUserDetails(this.userdetails)
.subscribe(
(response) => {
console.log('response received')
this.isSuccess= true;
},
(error) => {
console.error('error caught in updating user details')
this.errorMessage = error;
this.isSuccess= false;
}
)
// This value should be updated only if above two is successful
this.displayMessage=true;
}
}
You can use switchMap
to accomplish this.
// First API call
this.myService.getUserDetails(this.userid).pipe(
// Logging is a side effect, so use tap for that
tap(res => console.log('First API success', res)),
// Call the second if first succeeds
switchMap(resultFromUserDetails => this.myService.updateUserDetails(this.userdetails).pipe(
// Handle your error for second call, return of(val) if succeeds or throwError() if you can't handle it here
catchError(err => {
console.log('Error for second API (you can use statusCode here)', err);
return of();
}),
// Logging is a side effect, so use tap for that
tap(res => console.log('Second API success', res)),
)),
// Handle your error for first call, return of(val) if succeeds or throwError() if you can't handle it here
catchError(err => {
console.log('Error for first API (you can use statusCode here)', err);
return of();
})
).subscribe(
// handle both successfull
resultFromUpdateUserDetails => {
console.log('Both APIs succeeded, result from 2) is returned', resultFromUpdateUserDetails);
},
// handle uncaught errors
err => {
console.log('Any error NOT handled in catchError() or if you returned a throwError() instead of of() inside your catchError(), err);
}
)
Update: You can, of course, do some logic inside your switchMap
this.myService.getUserDetails(this.userid).pipe(
switchMap(res => {
// do something with res, or other logic here
// make sure to return your new observable at the end
return this.myService.updateUserDetails(this.userdetails);
})
);