Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS watch an object property in an object array

I have this data in my controller

    $scope.data = {
        home: {
            baseValue: "1",
            name: "home"
        },
        contact: {
            baseValue: "2",
            name: "contract"
        }
     // a lot more options
    };

with some html like this:

<section class="content row" ng-repeat="item in data">
   {{item.name}}
   ....
</section>

Now, I want to know when the baseValue is changed but because of I using a objects inside the data variable I can not watch the property in a simpler way.

I have tried something like this, but I have to loop all the array

$scope.$watch('data', function (newValue, oldValue, scope) {
 // some code to compare the tow arrays, line by line
}, true);

How can I do a simpler $watch to know only when the baseValue is changed?

Similar questions:

  • AngularJS watch array of objects for data change
  • How to get an object that was changed in angularjs?
  • How to deep watch an array in angularjs?

UPDATE 1

I could add an individual watch for each object to know when the baseValue is changed, but it won't be nice if I had an n number of objects, not only a couple of objects like in this example

$scope.$watch('data.home', function (newValue, oldValue, scope) {
 // do some stuff with newvalue.baseValue
}, true);

$scope.$watch('data.contact', function (newValue, oldValue, scope) {
 // do some stuff with newvalue.baseValue
}, true);
... // Adds more individual `watch`
like image 793
Coyolero Avatar asked Jul 22 '14 00:07

Coyolero


People also ask

What is an object property JS?

A JavaScript object has properties associated with it. A property of an object can be explained as a variable that is attached to the object. Object properties are basically the same as ordinary JavaScript variables, except for the attachment to objects.

What is $Watch in AngularJs?

$watch() function is used to watch the changes of variables in $scope object. Generally the $watch() function will create internally in Angularjs to handle variable changes in application.

Can a property of an object be an array?

Just as object properties can store values of any primitive data type (as well as an array or another object), so too can arrays consist of strings, numbers, booleans, objects, or even other arrays.


3 Answers

Based on your question, you can use ngChange to watch changes of baseValue and trigger the function.

HTML

<section class="content row" ng-repeat="item in data">     Name: {{item.name}} <br/>     BaseValue: <input type="text" ng-model="item.baseValue" ng-change="baseValueChange(item.baseValue)"/> </section> 

Controller

$scope.baseValueChange = function(baseValue) {     console.log("base value change", baseValue); } 

If you a more sophisticated version which can get oldValue and newValue, you can refer to this plunkr - http://plnkr.co/edit/hqWRG13gzT9H5hxmOIkO?p=preview

HTML

<section class="content row" ng-repeat="item in data">     Name: {{item.name}} <br/>     BaseValue: <input type="text" ng-init="item.oldBaseValue = item.baseValue" ng-model="item.baseValue" ng-change="baseValueChange(item.oldBaseValue, item.baseValue); item.oldBaseValue = item.baseValue"/> </section> 

Controller

$scope.baseValueChange = function(oldVal, newVal) {     console.log("base value change", oldVal, newVal); } 
like image 64
hutingung Avatar answered Sep 21 '22 20:09

hutingung


You can watch an object attribute.
So you can do something like

for(var key in $scope.data) {
  if($scope.data.hasOwnProperty(key)) {
    $scope.$watch("data['" + key + "'].baseValue", function(val, oldVal) {
      // Do stuff
    });
  }
}

Not tested, but the idea is simple.

like image 44
Jerska Avatar answered Sep 20 '22 20:09

Jerska


In this kind of scenario there is no way to circumvent utilizing multiple watches, another way to do this is by utilizing $watchCollection to watch the array of object values, you can get this array using the Object.values function.

scope.$watchCollection(function() {
    return Object.values(obj);
}, function(newValues, oldValues) {
    // now you are watching all the values for changes!
    // if you want to fire a callback with the object as an argument:
    if (angular.isFunction(scope.callback())) {
        scope.callback()(obj);
    }
});
like image 36
svarog Avatar answered Sep 21 '22 20:09

svarog