2

I have a parent component receives data from the server, and has to create a specific (and different) object that will be sent to the server any time the info is updated. Parent controller:

function ParentController() {
  this.$onInit = () => {
  // get user data from server
    this.userDataObject = {
      userInformation: {
        firstName: response.data.firstName,
        lastName: response.data.lasName,
      },
      contactInformation: {
        email: response.data.email,
        phone: response.data.phone
      }
    }
  }
    this.saveToDB = () => {
        httpPostCall(this.userDataObject);
    }
}

Each property of data is passed to a child component which is essentially an input element (with complex display logic, hence separated into a different component). Parent template:

<parent-component>
    <child-component save-value="$ctrl.saveToDB()"
        field-value="$ctrl.userDataObject.userInformation.firstName">
    </child-component>
</parent-component>

The child is an input field with two-way data binding to relevant property on userDataObject:

bindings: {
    fieldValue: '=',
    saveValue: '&'
}

And then the child binds the field value to input value via NgModel (using placeholder text if field value is empty). The value binding to the model works fine, so parent component data changes when the user provides input:

<div>
    <input ng-model="$ctrl.fieldValue">
    <button ng-click="$ctrl.saveValue()">OK</button>
</div>

This works in that a change to the input changes buyerDataObject and then on saving updates the database.

However, it also works if no change has been made to fieldValue, so if the user clicks the button without changing the value, it will still save to the DB. I want to find a way to determine whether the value has changed.

I've tried saving the value of fieldValue to a local variable in child component in $onInit, but it returns undefined. I can watch the variable and save the initial value, but would rather avoid adding watchers to the mix. It feels like there should be a more straightforward way to solve this problem.

NbonD
  • 317
  • 6
  • 17
  • 1
    You can set form with your input fields and use properties of input like pristine,dirty and touched to check the values and determine weather value is changed or not – Devang Naghera Jan 01 '18 at 13:43

1 Answers1

1

If you wrap your input fields in a form tag and link it to your controller

<form name="$ctrl.anyFormName">
    <input ng-model="$ctrl.fieldValue">
    <button ng-click="$ctrl.saveValue()">OK</button>
</div>

You can then get useful information about whether the field data has been modified in your controller. So you could change your save method to look something like

    this.saveToDB = () => {
        if($ctrl.anyFormName.$dirty) {
            httpPostCall(this.userDataObject);
        }
    }

Or you could just disable your save button until the form has been dirtied.

<button ng-click="$ctrl.saveValue()"
        ng-disabled="$ctrl.anyFormName.$pristine">
OK
</button>

You can find all of the angular form properties here: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

You can also use these methods to set your form to pristine after populating it with data.

init fail
  • 389
  • 1
  • 2
  • 15