如何将来自 API 请求的数据设置为变量,以便我可以在另一个 API 调用中使用它?

How do I set data from an API request to a variable so that I can use it in another API call?

我使用 MSAL 登录应用程序。登录后,我调用 Microsoft Graph API 获取当前用户的电子邮件,然后我想将其传递给另一个 API。每次我尝试传递此数据时,它都未定义。

这是我的组件中用于从 Microsoft 调用 API 的方法。

userEmail: string | undefined;

 getProfile(){
    this.http.get(GRAPH_ENDPOINT)
      .subscribe((profile: ProfileType) => {
        this.userEmail = profile.userPrincipalName; //setting userEmail to the returned email address
        console.log(this.userEmail); //logging the email address
      });   
  }

然后,在我的组件的 ngOnInit 方法中我写:

 ngOnInit(): void {
      this.getProfile();
      console.log(this.userEmail) //logging the returned email address
 }

这个控制台输出

undefined // the console log from ngOnInit from userEmail
test@microsoft.com // console log from http request

这是我保留 运行 并且找不到解决方法的错误。 我希望能够将 userEmail 设置为 Microsoft Graph API 中 return 的帐户电子邮件地址,以便我可以在另一个 API呼叫.

您的 ngOnInit 存在某种竞争条件。您必须等待 http 请求完成,然后才能将其登录到控制台或对另一个请求使用响应。

示例:https://stackblitz.com/edit/rxjs-whdaaq

import { concat, timer } from "rxjs";
import { mapTo, tap } from "rxjs/operators";

let mail: any = "Unknown";

// Simulate an http request
function getProfileData$(delay): any {  
  return timer(delay).pipe(
    mapTo('mail@fake.com'),
    tap(profileData => (mail = profileData))
  );
}

// This should be on your ngInit
getProfileData$(100).subscribe(() => {
  console.log("Value after emit:", mail);
});
console.log("Value before emit:", mail);

// You can also chain observables with concat
concat(
  getProfileData$(1000).pipe(mapTo('First')),
  getProfileData$(1000).pipe(mapTo('Second')),
  getProfileData$(2000).pipe(mapTo('Third'))
).subscribe(console.log);

在这种情况下,理想的解决方案是使用 Rxjs 运算符 'mergeMap' 链接两个 api 调用。

示例:

this.http
 .get("https://reqres.in/api/users?page=1")
   .pipe(
     mergeMap(users =>
      this.http.get("https://reqres.in/api/users/" + users["data"][1].id)
    )
   )
   .subscribe(res => (this.user = res));

在上面的示例中,我们从 api 获取用户列表,然后将用户 ID 从它传递到第二个 api 以获取用户详细信息。

Stackblitz - https://stackblitz.com/edit/angular-api-call-euz5jq?file=src/app/app.component.ts