无法读取 Object.eval [as updateDirectives] 处未定义的属性“性别”

Posted

技术标签:

【中文标题】无法读取 Object.eval [as updateDirectives] 处未定义的属性“性别”【英文标题】:Cannot read property 'gender' of undefined at Object.eval [as updateDirectives] 【发布时间】:2020-07-15 23:06:12 【问题描述】:

我正在创建一个社交媒体应用程序,但我不确定为什么在导航到新用户的设置页面时总是出现此错误。问题是数据库中没有这些字段的值。

这是代码。

  userSettings: IUserSettings = 
    gender: null,
    drinks: null,
    smoking: null,
    ageRange: this.ageRange,
    distance: this.distance,
    notifications: true,
    dateOfBirth: null
  ;


  ngOnInit() 
    console.log('settings', this.userSettings)
    this.afAuth.authState.subscribe(user => 
      this.getDataSvc.getUserFromFirebase(user.uid)
        .then((data) => 
          this.userSettings = data.data().userSettings;
        ).catch((error) => 
          console.log('errr', error);

        );
    );
  
      <ion-button expand="block" color="success" style="margin-bottom: 20px;">
        <ion-icon size="large" name="transgender-outline" padding-left="20px"></ion-icon>
        <ion-select id="gender" name="gender" placeholder="Gender" required #genderField="ngModel"
          [(ngModel)]="userSettings.gender" [class.field-error]="form.submitted && genderField.invalid">
          <ion-select-option>Female</ion-select-option>
          <ion-select-option>Male</ion-select-option>
          <ion-select-option>Other</ion-select-option>
          <ion-select-option>No Preference</ion-select-option>
        </ion-select>
      </ion-button>
      <div [hidden]="genderField.valid || genderField.untouched" class="alert alert-danger">
        Must select an option
      </div>

我最初以为我可以向 [(ngModel)]="userSettings?.gender" 添加一个空检查,但这不起作用。

当我进入设置页面时,它只是一直显示相同的错误:

ProfileSettingsPage.html:16 ERROR TypeError: Cannot read property 'gender' of undefined
    at Object.eval [as updateDirectives] (ProfileSettingsPage.html:17)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:45259)
    at checkAndUpdateView (core.js:44271)
    at callViewAction (core.js:44637)
    at execComponentViewsAction (core.js:44565)
    at checkAndUpdateView (core.js:44278)
    at callViewAction (core.js:44637)
    at execEmbeddedViewsAction (core.js:44594)
    at checkAndUpdateView (core.js:44272)
    at callViewAction (core.js:44637)

【问题讨论】:

尝试将 *ngIf="userSettings" 添加到包装容器中。由于您有异步订阅,因此您的模板可能会在您的对象返回之前尝试显示。 我应该把它放在代码的什么地方? 尝试添加一个包含整个模板的 div 【参考方案1】:

您看到的错误是因为 DOM 元素甚至在您获得 userSettings 值之前就已加载。 正如@robbieAreBest 所提到的。您需要将父块包装在 *ngIf 中以检查 userSettings。

您的 ion-select 在加载时不知道 userSettings 是什么。

    <ion-button *ngIf="userSettings" expand="block" color="success" style="margin-bottom: 20px;">
            <ion-icon size="large" name="transgender-outline" padding-left="20px"></ion-icon>
            <ion-select id="gender" name="gender" placeholder="Gender" required #genderField="ngModel"
              [(ngModel)]="userSettings.gender" [class.field-error]="form.submitted && genderField.invalid">
              <ion-select-option>Female</ion-select-option>
              <ion-select-option>Male</ion-select-option>
              <ion-select-option>Other</ion-select-option>
              <ion-select-option>No Preference</ion-select-option>
            </ion-select>
          </ion-button>
<span *ngIf="!userSettings">Loading data...</span> // this is optional

【讨论】:

当我添加 ngIf 元素时,它永远不会加载。即使我在 .ts 文件中手动向 userSettings 添加值,元素也不会加载。 你能在stackblitz上发布你的解决方案吗?或至少整个 html 在这里。 发布了答案@saidutt。想法? 看起来不错,不知道是嵌套的。无论如何,您不能将其简化为 this.userSettings = data.data().userSettings !?只是好奇【参考方案2】:

所以我没有使用对象,而是使用原始类型作为我的 ngModel 来解决这个问题。

 gender: string;
  drinks: string;
  smoking: string;
  notifications: boolean = true;

  userSettings: IUserSettings = 
    gender: null,
    drinks: null,
    smoking: null,
    ageRange: this.ageRange,
    distance: this.distance,
    notifications: true,
    dateOfBirth: null
  ;

  validations_form: FormGroup;
  errorMessage: string = '';

  constructor(private router: Router,
    private dataSvc: DataService,
    private afAuth: AngularFireAuth,
    private getDataSvc: GetDataService,
  )  

  ngOnInit() 
    console.log('settings', this.userSettings)
    this.afAuth.authState.subscribe(user => 
      this.getDataSvc.getUserFromFirebase(user.uid)
        .then((data) => 
          this.gender = data.data().userSettings.gender,
            this.drinks = data.data().userSettings.drinks,
            this.ageRange = data.data().userSettings.ageRange,
            this.distance = data.data().userSettings.distance,
            this.notifications = data.data().userSettings.notifications
        ).catch((error) => 
          console.log('errr', error);
        );
    );
  

  goToProfilePage() 
    this.router.navigateByUrl('tabs/profile');
  

  savePersonalInfo(form) 
    console.log(form.valid);
    if (form.valid) 
      this.userSettings = 
        gender: form.value.gender,
        drinks: form.value.drinks,
        smoking: form.value.smoking,
        ageRange: this.ageRange,
        distance: this.distance,
        notifications: this.notifications,
        dateOfBirth: null
      ;
      this.dataSvc.addUserSettings(this.userSettings).then(() => 
        this.goToProfilePage();
      
      )
    
    <ion-card >
      <ion-button  expand="block" color="success" style="margin-bottom: 20px;">
        <ion-icon size="large" name="transgender-outline" padding-left="20px"></ion-icon>
        <ion-select id="gender" name="gender" placeholder="Gender" required #genderField="ngModel"
          [(ngModel)]="gender" [class.field-error]="form.submitted && genderField.invalid">
          <ion-select-option>Female</ion-select-option>
          <ion-select-option>Male</ion-select-option>
          <ion-select-option>Other</ion-select-option>
          <ion-select-option>No Preference</ion-select-option>
        </ion-select>
      </ion-button >
      <div [hidden]="genderField.valid || genderField.untouched" class="alert alert-danger">
        Must select an option
      </div>

当我在 HTML ngModel 中使用原始类型时它可以工作

【讨论】:

以上是关于无法读取 Object.eval [as updateDirectives] 处未定义的属性“性别”的主要内容,如果未能解决你的问题,请参考以下文章

AS3读取txt文档

AS3读取txt文档

as3中xml文件的加载和读取

ActionScript 3 使用AS3读取不同的文件类型

用AS3读取不同的文件类型

AS3 用ShareObject保存数据之后,发布成exe时不能读取数据