如何使用带条件的 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);
   })
);