【问题标题】:How do I set data from an API request to a variable so that I can use it in another API call?如何将 API 请求中的数据设置为变量,以便在另一个 API 调用中使用它?
【发布时间】:2021-03-24 22:00:21
【问题描述】:

我使用 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 返回的帐户电子邮件地址,以便我可以在另一个 API 调用中使用它。

【问题讨论】:

    标签: angular typescript api msal


    【解决方案1】:

    在这种情况下,理想的解决方案是使用 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

    【讨论】:

      【解决方案2】:

      您的 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);
      

      【讨论】:

        猜你喜欢
        • 2021-06-10
        • 2021-09-23
        • 2019-06-24
        • 2020-11-06
        • 1970-01-01
        • 1970-01-01
        • 2019-11-06
        • 2021-05-15
        • 1970-01-01
        相关资源
        最近更新 更多