1

I might be using this wrong, but I have a function that watches a variable and when that variable is changed from the view, the function runs.. but when a sibling function changes that variable the watch doesn't run. Am I coding something wrong?

scope.$watch (settings.number, function(val){
    alert('test');
})
scope.exampleObj = {
    exampleFunc : function(){
        settings.number += 5;
    }
};

so when I call scope.exampleObj.exampleFunc(); shouldn't scope watch get called?

1
  • I think changes within children do not trigger the change. Can you try watching on number itself, and updating the number rather than enclosing in parent object. Not sure, but I had same issue on an older version of angular Commented Apr 22, 2014 at 22:30

3 Answers 3

2

Replace string to a function or use $watchCollection, like this:

Using var:

angular.module('TestApp', [])
    .controller('MainCtrl', function($scope){
        // Object
        var settings = {
            number: 1,
            foobar: 'Hello World'
        };

        $scope.$watch(function(){ return settings.number; }, function(newValue, oldValue){
            console.log('New value detected in settins.number');
        });

        $scope.$watchCollection(function(){ return settings; }, function(newValue, oldValue){
            console.log('New value detected in settings');
        });
    });

Using $scope:

angular.module('TestApp', [])
    .controller('MainCtrl', function($scope){
        // Object
        $scope.settings = {
            number: 1,
            foobar: 'Hello World'
        };

        $scope.$watch('settings.number', function(newValue, oldValue){
            console.log('New value detected in $scope.settings.number');
        });
    });

Example: http://jsfiddle.net/Chofoteddy/2SNFG/

*Note: $watchCollection that is available in AngularJS version 1.1.x and above. It can be really useful if you need to watch multiple values in a array or multiple properties in a object.

Sign up to request clarification or add additional context in comments.

Comments

1

The watcher expects the name(ie. string) of a property of inside the scope, not the object itself.

scope.$watch ('settings.number', function(newval,oldval){
   alert('test');
});
  scope.exampleObj = {
  exampleFunc : function(){
      scope.settings.number += 5;
  }
};

I'm assuming the somewhere you declare scope.settings.number first, and that you meant to set scope.settings.number not settings.number as you can only watch variables which are properties of the angular scope.

Though you may be doing the right thing with just settings.number += 5;, I may just be tired.

3 Comments

@marck, why thank you kind sir for the fiddle :). I am assuming the problem was one of not watching a $scope variable.
@marck the variable is declared higher up, turns out the issue wasn't with this part.. It works unless I have the number updated with a time interval.
@pashOCONNOR, does the timer interval use the $scope.apply function? reading material: jimhoskins.com/2012/12/17/angularjs-and-apply.html
0

You need to set the objectEquality to true . so you can compare for object equality using angular.equals instead of comparing for reference equality.

for more infos visit the documentation

scope.$watch (settings.number, function(val){
    alert('test');
},true)
scope.exampleObj = {
    exampleFunc : function(){
        settings.number += 5;
    }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.