2

I am not able to watch the work when it is placed on an element within an array;

See the example: http://jsfiddle.net/zwrza551/2/

<div ng-app>
    <div ng-controller="Test">
        Name: <input type="text" ng-model="customer.name" />
        <hr/>
        <div ng-repeat="address in customer.addresses">
            <input type="text" ng-model="address.name" />
            <input type="text" ng-model="address.zipcode" />
            <hr />
        </div>
    </div>
</div>

function Test($scope){
    $scope.customer = {
        name: 'Customer 1',
        addresses: [
            { name: 'Address 1', zipcode: 123456, city: null, state: null },
            { name: 'Address 2', zipcode: 234567, city: null, state: null },
            { name: 'Address 3', zipcode: 456787, city: null, state: null },
            { name: 'Address 4', zipcode: 675684, city: null, state: null }
        ]
    };    

    $scope.$watch('customer.name', function(newName, oldName){
        console.log(newName);
    });

    $scope.$watch('address.zipcode', function(newCode, oldCode){
        console.log(newCode);
        //Make request to webservice, get addres for zipcode set city and state from this address.
    });
}

On name of the client I can, since the array of addresses does not work.

Tolga Evcimen
  • 7,112
  • 11
  • 58
  • 91
Daldegam
  • 121
  • 4
  • your addresses are a member of customer, so you would need to use `customer.addresses`. Though, I don't know if you can watch specific indices of an array. – Jonas Nov 10 '14 at 12:52
  • 1
    possible duplicate of [$watch an object in angular](http://stackoverflow.com/questions/19455501/watch-an-object-in-angular) – Joseph Nov 10 '14 at 12:52
  • @Jeyp I can not watch the whole object. I need to know only the zip code. If the guy change for example the number of his residence, the object will be changed. So only need to know the zip code is changed. – Daldegam Nov 10 '14 at 13:01
  • Well, okay. Then I'd suggest another apporach. Why don't you use a change listener on that field and update the other values accordingly? This seems to be some kind of autocompletion, and you do this stuff usually by reacting to change events on a text field. – Jonas Nov 10 '14 at 13:04
  • why you are not using ng-change directive for that. – Mukund Kumar Nov 10 '14 at 13:07
  • @MukundKumar Really. Managed to solve with the ng-change! Thank you! :) – Daldegam Nov 10 '14 at 13:21

3 Answers3

0

Try to go with that:

$scope.$watch('customer.addresses', function(newCode, oldCode){
    for (... every address in customer.addresses) {
        // check if city and state are null and do the request if it is true
    }
}, true);

Don't forget to turn the deep watch switch on. (the 3rd argument true) The switch enables checking witch angular.equals instead of comparing references, which results in you array being watched on changes in its elements.

Jonas
  • 1,315
  • 1
  • 18
  • 31
  • That would not work the way I need. I need it to monitor only the zip code and return to me the new zip – Daldegam Nov 10 '14 at 13:06
  • Can you write that in english please? – Jonas Nov 10 '14 at 13:07
  • See an example of where I'll use it. http://prntscr.com/54xbhp I have several elements that depend on the zip code; However the reference field can be changed without the monitor redo the request. Therefore it is important that only make the request when the zip is changed; – Daldegam Nov 10 '14 at 13:13
  • Yes you should use [ngChange](https://docs.angularjs.org/api/ng/directive/ngChange) then. I was suggesting you to use a change listener in my second comment in your question... – Jonas Nov 10 '14 at 13:25
0

Ng-repeat has its own scope, so u can not write 'address.zipcode' outside. (I mean, u can write, but this will address another variable) You can write:

$scope.$watch('customer.addresses[0].zipcode', function(newCode, oldCode){
    console.log(newCode);
});

And same for all indices... But as one said before, better use ng-change. http://jsfiddle.net/qnb5aL1p/

Petr Averyanov
  • 9,327
  • 3
  • 20
  • 38
0

You can use this work around.i:e to add multiple watches but better to go with ng-change which @Petr had already explained above

You are facing this issue as ng-repeat has it's own isolated scope, which is out of scope of your current $scope.

for (var i = 0; i < $scope.customer.addresses.length; i++) {
    $scope.$watch('customer.addresses[' + i + ']',function(newValue, oldValue) {
        console.log(newValue.zipcode + ":::" + oldValue.zipcode);
    }, true);
}  
KanhuP2012
  • 407
  • 3
  • 9