guidsen
guidsen

Reputation: 2403

$watch not updating in ng-repeat

I'm trying to calculate a total by multiplying 2 ng-models. The models are in a ng-repeat, where I have a own controller for the rows.

On reload, it does the console log, but when I update the ng-models, they don't console log anymore and just don't work.

The controller:

app.controller('RowCtrl', function ($scope) {
   $scope.unit_price = 0;
   $scope.quantity = 0;

   $scope.$watchCollection('[unit_price, quantity]', function(newValues) {
      console.log(parseInt(newValues));
   }, true);

   $scope.total = $scope.unit_price * $scope.quantity;
});

UPDATED with fiddle: http://jsfiddle.net/r9Gmn/

Upvotes: 1

Views: 722

Answers (4)

gkalpak
gkalpak

Reputation: 48211

This should work fine (if implemented correctly), i.e. your logic is correct:

<div ng-controller="myCtrl">
    Unit price:
    <input type="number" ng-model="unit_price" />
    <br />
    Quantity:
    <input type="number" ng-model="quantity" />
    <hr />
    Total: {{total}}
</div>

app.controller('myCtrl', function ($scope) {
    $scope.unit_price = 0;
    $scope.quantity   = 0;

    $scope.$watchCollection('[unit_price, quantity]', function(newValues) {
        $scope.total = $scope.unit_price * $scope.quantity;
    });
});

See, also, this short demo.

Upvotes: 0

Michael Kang
Michael Kang

Reputation: 52847

Watch a function that calculates the total:

$scope.$watch(function() { 
  return unit_price * quantity;
}, function(newVal) {
  $scope.total = newVal;
});

Upvotes: 3

m.e.conroy
m.e.conroy

Reputation: 3538

Here's your fiddle working: http://jsfiddle.net/mikeeconroy/r9Gmn/1/

In your $scope.rows array on the controller you never defined the properties to be used in the RowCtrl's scope. Also you should make sure you use track by with ng-repeat so you don't get the dupes error.

var app = angular.module('myApp', []);
app.controller('RowCtrl', function ($scope) {
    $scope.total = 0;
    $scope.$watchCollection('[row.unit_price, row.quantity]', function(newValues)         {
        $scope.total = parseInt(newValues[0]) * parseInt(newValues[1]);
    });
});

app.controller('MainCtrl', function ($scope) {
    $scope.rows = [
        { unit_price: 10, quantity: 0 },
        { unit_price: 12, quantity: 0 },
        { unit_price: 15, quantity: 0 },
    ];
});

Upvotes: 0

Ilan Frumer
Ilan Frumer

Reputation: 32377

I agree with @pixelbits answer.

Just to add that as of angular 1.3 there is a new scope method $watchGroup:

An example http://plnkr.co/edit/2DvSmxUo5l8jAfBrSylU?p=preview

Solution:

$scope.$watchGroup(['unit_price', 'quantity'], function(val) {
  $scope.total = val[0] * val[1];
});

Upvotes: 1

Related Questions