【问题标题】:Cannot read property 'first_name' of undefined无法读取未定义的属性“first_name”
【发布时间】:2019-02-10 20:17:03
【问题描述】:

我有这个问题

无法读取未定义的属性“first_name”

这是我的 HTML 文件 checkout.html

<ion-content>
      <ion-item>
        <ion-label>First Name</ion-label>
        <ion-input type="text" [(ngModel)]="newOrder.billing.first_name"></ion-input>
      </ion-item>
      
      ....
      
</ion-content>

这是我的 ts 文件 checkout.ts

      this.storage.get("userLoginInfo").then((userLoginInfo) => {

      this.userInfo = userLoginInfo.user;

      let email = userLoginInfo.user.email;
      let id = userLoginInfo.user.id;

      this.WooCommerce.getAsync("customers/email/"+email).then((data) => {

        this.newOrder = JSON.parse(data.body).customer;

      })

    })

这是错误的图像

【问题讨论】:

  • 显然billing 属性是undefined 就像错误提示的那样。这是异步的,因此模板在数据到达之前呈现。当然它可能是undefined,原因是该道具不存在,但我猜问题是第一个。
  • newOrder 里面有什么?
  • 我已经在构造函数 this.newOrder = {} 中声明了它; this.newOrder.billing = {}; this.newOrder.shipping = {}; this.billing_shipping_same = false;
  • 好的,那么您获得的数据可能不存在billing 属性。就像 NullPointer 评论的那样,分配数据后newOrder 的内容是什么?

标签: javascript angular typescript ionic3 woocommerce-rest-api


【解决方案1】:

您似乎正在异步加载 newOrder。 结果你的页面被渲染了,但是异步任务还没有完成。

您写道,您在构造函数中声明了this.newOrder.billing = {}。 因此,他现在尝试在您的 html 中读取 newOrder.billing.first_namenewOrder.billing 是一个空对象,所以那里没有 first_name

只有当异步任务完成时,该数据才会存在。但目前 Angular 在此之前会抛出一个错误。

有两种非常常见的方法来处理这种情况。

你可以告诉模板它不应该渲染缺少数据的部分

<ion-item *ngIf="newOrder.billing">
  <ion-label>First Name</ion-label>
  <ion-input type="text" [(ngModel)]="newOrder.billing.first_name"></ion-input>
</ion-item>

然后 *ngIf 将看到变量未定义并且模板的那部分不会显示在 DOM 中 => 没有错误 :-) 异步任务完成后,变量不再未定义,模板部分将显示出来。

另一种方式(当您只想显示数据时更常见)是使用 {{ newOrder.billing.first_name | async }} 异步管道还将确保 Angular 可以处理那个。 结合 [ngModel] 我认为异步管道将不起作用。但可能值得一试。

热烈的问候

【讨论】:

  • ...好吧,如果billing 是一个空对象,它怎么可能同时是undefined? ;)
  • :-) True :-) ,所以另一种选择是,“JSON.parse(data.body).customer”返回未定义
【解决方案2】:

只需添加一个引号,我认为它会有所帮助。

<ion-input type="text" [(ngModel)]="newOrder?.billing.first_name"></ion-input>

【讨论】:

    【解决方案3】:

    您可以在插值中对对象简单地使用引号,如 @Kraken。

    但是@JanRecker 提供了两个解决方案: 如果您在插值中使用异步管道,它将不起作用,因为这适用于 Observables rxjs

    因此,添加引号确实是一个有用的选项。

    【讨论】:

      猜你喜欢
      • 2017-10-11
      • 2018-05-15
      • 2019-05-08
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2020-10-30
      相关资源
      最近更新 更多