ngChange is called when model changed programmatically

All we need is an easy explanation of the problem, so here it is.

I have a problem when angular’s ng-change is called when model is changed programmatically.

$scope.sendMessage = function() {
    $scope.message = "Message sent";

$scope.confirmed = true;
$scope.mySelectBox = $scope.selects[1];

<select ng-model="mySelectBox"
        ng-options=" for item in selects track by"

Here is code example:

Message should be null, because sendMessage shouldn’t be called. Model is changed programmatically.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You can try with ngModelOptions. See this plunker for reference

In my example I used ng-model-options="{ updateOn: 'change', debounce: { change: 0 } }" and it seems to work. It only runs function provided in ngChange when I change the selection. On initialize phase message stays empty.

Method 2

The ng-change callback is changed on each model change, and it treats the initial setup as such change. What you might want to do is to run desired code only after user interacts with it. You can check the $touched property of the field:

<form name="exampleForm" ng-controller="ExampleController">
  <select ng-model="mySelectBox" name="mySelectBox"
          ng-options=" for item in selects track by"
  <p>message = {{message}}</p>

$scope.sendMessage = function() {
    if ($scope.exampleForm.mySelectBox.$touched) {
        $scope.message = "Message sent";

Method 3

According to docs, you’re right.

but this seems to be a bug caused by the order in which the events are hooked up

The best way round it – with resorting to js handler (onchange)

$scope.$watch("mySelectBox", function(a,b) {
    if (! {
       $scope.message = "Message sent! (old="', new='')';

See plunk


Method 4

You are providing value to model in controller ,so whenever you will set value of model which is matching with list it will call ng-change:

See updated plunker:

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply