Why does this $scope.$watch not work?


#1

I can’t figure out what I am doing wrong? I need to get the new selected value into the controller.

Thanks.


#2

There are two problems with this. First, watching primitive values doesn’t really work because when you change the value of a primitive you get a new reference. To get around this, you have to wrap your primitive in an object and watch the object like this:

  $scope.model = {myNumber: 3};
  
  $scope.$watch("model.myNumber", function(newValue, oldValue){
    $scope.update = newValue;
  });

and then your html would look like this:

<select ng-model="model.myNumber" ng-options="number.key as number.value for number in numbers" ng-change="valueChanged()">
    </select>

The other problem with your codepen is your watch had the new and old values switched. The new value is the first parameter.


#3

I could not understand why people were using objects when a primitive would seem to work just fine. But I see why now.

I am now getting the updated value in the controller but for some reason my select does not populate with the starting value. I just have to keep hacking on it.

I’d not come across valueChanged() in anything I was reading. It seems like one of those “magical” settings you just need experience to know about.

Thank you for your help. I really appreciate it.


#4

The valueChanged() is not magical, it just doesn’t exist in your context. ng-change gets called when the user changes the value of the select. It’s generally preferred over doing watches because watches run every digest cycle where the ng-change is just a callback function. You can get rid of your $watch and do this:

$scope.valueChanged = function(){
    $scope.update = $scope.model.myNumber;
}