formData not changing with ngChange hook

382 Views Asked by At

I have a very basic scenario where in which I have a module with one controller:

var myModule = angular.module('myModule', []);

myModule.controller('myModuleCtrl', function ($scope, $http) {
    $scope.formData = {url:'',title:'',source:''};

    $scope.init = function() {
        $scope.formData.url = 'Test';
        $scope.formData.title = '';
        $scope.formData.source = '';
    };

    $scope.manageUrl = function() {
        alert('update');
    };
});

In my view I'm trying to hook the formData object properties to some form fields using ngModel. However my input doesn't update it's value after the init() method runs. If I add the ngChange directive and hook that up with the $scope.manageUrl() method, it only runs once, after my first keystroke/change of the input.

Am I missing something here? I've used both directives before without any problems. Only thing I can think of is something wrong with my module/controller setup?

This is what my view looks like:

<div ng-app="myApp" ng-controller="myModuleCtrl" ng-init="init()">
    <div>
        <form name="myForm">
            <div>
                <input type="url" ng-model="formData.url" ng-change="manageUrl()" />
            </div>
        </form>
    </div>
</div>

And my application.js bootstrapper:

var app = angular.module('myApp', ['myModule']);
1

There are 1 best solutions below

1
On BEST ANSWER

It happens because of the url validator, note how the whole url property is removed until you enter a valid url, that's when you'll start to get your alerts back. Basically, once removed, the url is never considered to be changed until a valid (and different) url is input.

  • url is set to 'Test'
  • you type anything into the box, it fails the validation and becomes undefined
  • it stays undefined until you enter a valid url (it's not changing)

Start typing http://anything and see what happens yourself:

var myModule = angular.module('myModule', []);

myModule.controller('myModuleCtrl', function ($scope, $http) {
    $scope.formData = {url:'',title:'',source:''};
    $scope.init = function() {
        $scope.formData.url = 'Test';
        $scope.formData.title = '';
        $scope.formData.source = '';
    };

    $scope.manageUrl = function() {
        alert('update');
    };
});

var app = angular.module('myApp', ['myModule']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myModuleCtrl" ng-init="init()">
    <div>
        <form name="myForm">
            <div>
                <input type="url" ng-model="formData.url" ng-change="manageUrl()" />
              
              <br>
              {{formData}}
            </div>
        </form>
    </div>
</div>


Am I missing something here? I've used both directives before without any problems. Only thing I can think of is something wrong with my module/controller setup?

The only logical solution that comes to my mind is that you've used a different input type before, so you were not a subject to validations. If you change the type to text, it works fine the whole time.