如何使用带条件的 ConcatMap 进行多次 API 调用
How to make multiple API calls using ConcatMap with conditions
在 Angular 7 中,我试图依次调用两个不同的 API 方法。如果第一个成功则需要调用第二个 API 方法。
如果第一个 API 响应代码是 500 内部服务器错误,则不应调用第二个 API。我还需要处理每个 API 调用的错误。
我尝试了 Promise、async 和 await 方法,但是当我检查开发人员工具时,可以看到第二个被调用,即使第一个 API 没有 return 任何响应。
有人可以帮助我使用 concatmap 或任何其他 Angular 方法来实现这一目标。
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;
}
}
您可以使用 switchMap
来完成此操作。
// 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);
}
)
更新:当然,您可以在 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);
})
);
在 Angular 7 中,我试图依次调用两个不同的 API 方法。如果第一个成功则需要调用第二个 API 方法。
如果第一个 API 响应代码是 500 内部服务器错误,则不应调用第二个 API。我还需要处理每个 API 调用的错误。
我尝试了 Promise、async 和 await 方法,但是当我检查开发人员工具时,可以看到第二个被调用,即使第一个 API 没有 return 任何响应。
有人可以帮助我使用 concatmap 或任何其他 Angular 方法来实现这一目标。
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;
}
}
您可以使用 switchMap
来完成此操作。
// 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);
}
)
更新:当然,您可以在 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);
})
);