Search code examples
angulardata-bindingbindingionic3ngmodel

Why is ionic 3 two way data binding not working?


please I'm trying to flesh out a registration page for my ionic ongoing project Trying to bind my ([ngModel]) to an object property in my component.

Let me just show the code excerpt so you'll understand

**Registration.ts** // This is my registration component
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';

@IonicPage()
@Component({
  selector: 'page-registration',
  templateUrl: 'registration.html',
})

export class RegistrationPage {
  newStaffInfo = {
      username: "",
      password: "",
      rePassword: "",
      email: "",
      sex: ""
  }


newStaffTemplateObject: Object = [
      {
        label: "Username",
        field: this.newStaffInfo.username,
      },

      {
        label: "Password",
        field: this.newStaffInfo.password  
      },

      {
        label: "Re-enter Your password",
        field: this.newStaffInfo.rePassword  
      },
      {
        label: "Email",
        field: this.newStaffInfo.email  
      },

      {
        label: "Sex",
        field: this.newStaffInfo.sex  
      },

  ];

  constructor(public navCtrl: NavController, public navParams: NavParams) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad RegistrationPage');
  }


  validateForm(){
      console.log("Validate in this functin...");
  }
}

This is my HTML Template

<ion-content padding>

    <form (ngSubmit)="validateForm()" #form="ngForm">
        <ion-list>

            <ion-item *ngFor="let item of newStaffTemplateObject">
                <ion-label floating> {{item.label}} </ion-label>
                <ion-input type="text" [(ngModel)]="item.field" name="item.label" #item.label="ngModel" required> </ion-input>
            </ion-item>

            <ion-item>
                <button ion-button outline block full> Register </button>
            </ion-item>

        </ion-list>
    </form>

<!-- For DEbugging puprpose only -->

{{newStaffInfo.username}}  //This is suppose to reflect changes immediately
</ion-content>

Even with the above setup, it's not working at all. What can i do here to make the two data binding work


Solution

  • In your code, you initialize the newStaffTemplateObject items with the properties of newStaffInfo:

    newStaffTemplateObject = [
      {
        label: "Username",
        field: this.newStaffInfo.username
      },
      {
        label: "Password",
        field: this.newStaffInfo.password
      },
      ...
    ];
    

    and then you bind the newStaffTemplateObject items to the input elements in the template.

    The data binding works: it updates the values of the newStaffTemplateObject items. However, it does not update the related properties in newStaffInfo (which is what you expected, according to your debugging markup). The reason: newStaffTemplateObject[0].field does not become a reference to newStaffInfo.username; it is a separate variable that does not maintain any link with it after having been initialized.

    One possible solution is to set each field value to the name of the property in newStaffInfo:

    newStaffTemplateObject = [
      {
        label: "Username",
        field: "username",
      },
      {
        label: "Password",
        field: "password"
      },
      {
        label: "Re-enter password",
        field: "rePassword"
      },
      {
        label: "Email",
        field: "email"
      },
      {
        label: "Sex",
        field: "sex"
      },
    ];
    

    and to bind the properties of newStaffInfo to your input elements using the bracket notation:

    <ion-item *ngFor="let item of newStaffTemplateObject">
      ...
      <ion-input type="text" [(ngModel)]="newStaffInfo[item.field]" ... > </ion-input>
    </ion-item>
    

    You can test the code in this stackblitz.