Sam
Sam

Reputation: 14596

angular: $watch set in a loop

I do the following

 $scope.product.orders.forEach(function (order) {
    $scope.$watch('order.details.items.length', function (n, o) {
       if (n !== o) {
          //do something
        }
     });
  }, true);

where details is an object and items is an array.

The $watch is triggered once for every orders in the collection, with n and o being undefined.

Then whenever I add an item to the items array, the $watch is not triggered. Why is that ? There is no errors in the log.

note: I know that creating a $watch in a loop is clearly not a good thing performance-wise, it's a workaround for now.

Upvotes: 2

Views: 1405

Answers (2)

Pascal Ockert
Pascal Ockert

Reputation: 984

If the first parameter of $scope.$watch is a string, it defines an expression that is evaluated on your scope. Usually this is a scope variable. In your case order is not a scope variable but a parameter of the forEach's handler function. You have to use the function way in this case:

 $scope.product.orders.forEach(function (order) {
    $scope.$watch(function () {
       return order.details.items.length;
    }, function (n, o) {
       if (n !== o) {
          //do something
        }
     });
  }, true);

Upvotes: 4

Tom Chen
Tom Chen

Reputation: 1518

For a collection object/array, you should use $scope.$watchCollection instead.

$scope.$watchCollection('order.details.items', function (collection) {
    // fires when collection changed, whenever it's length changed or item(s) changed.
})

Upvotes: 2

Related Questions