Angular JS: get ng-model on ng-change

Just for anyone else coming here, ng-change is actually called after the model value has been set.

Why?
Let's see when is it called. From the angular source code, ng-change is just an attribute directive with this directive definition object (DDO).

{
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attr, ctrl) {
      ctrl.$viewChangeListeners.push(function() {
        scope.$eval(attr.ngChange);
      });
    }
}

From this we see that the ng-change directive is very simple. All that ng-change='<expr>' does is add a function to the end of $viewChangeListeners that evaluates <expr> via $scope.$eval.

OK ... so when are the ViewChangeListeners called?

Well, if we look at the documentation for ngModel.NgModelController:

the new value will be applied to $modelValue and then the expression specified in the ng-model attribute. Lastly, all the registered change listeners, in the $viewChangeListeners list, are called.

So the viewChangeListener for the ngChange will be invoked after the value is applied to $modelValue. Hence the callback will be invoked after the model as been set.

Also note that this behavior is the same in all versions of angular. The definition for ng-change hasn't changed since v1.2.


The ng-change handler is fired before the ng-model is actually updated. If you want filterByCountry to be fired every time $scope.country changes (rather than just when the dropdown changes), you should use the following instead:

$scope.$watch('country', filterByCountry);

I always find it more useful to react to changes in my $scope rather than DOM events when possible.