html - Nu se poate citi proprietatea 'gender' a valorii nedefinite la Object.eval [ca updateDirectives]
Creez o aplicație de social media și nu sunt sigur de ce primesc această eroare când navighez la pagina de setări a unui utilizator nou. Problema este că nu există valori în baza de date pentru aceste câmpuri.
Iată codul.
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>Inițial am crezut că pot doar să adaug o verificare null la [(ngModel)]="userSettings?.gender", dar asta nu funcționează.
Când intru pe pagina de setări, continuă să afișeze aceeași eroare:
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)Răspuns #1
Eroarea pe care o vedeți apare pentru că elementele DOM sunt încărcate chiar înainte de a avea valoarea userSettings. Așa cum a menționat @robbieAreBest, trebuie să încadrați blocul părinte într-un *ngIf pentru userSettings.
Ion-select-ul tău nu știe ce sunt userSettings când este încărcat.
<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
Răspuns #2
Deci, în loc să folosesc un obiect, am folosit tipuri primitive ca ngModel pentru a rezolva această problemă.
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>Funcționează când folosesc tipuri primitive în HTML ngModel
