6

I am trying to create a function that will sum up some numbers from an incoming factory (and some from the client-side in real time), and will put the sum in the view. Totally stuck.

1 - First of all, I do not understand how to display in the view a variable that was assembled within a controller function.

So let's say I have something like:

$scope.total = function() {
    var totalNumber = 0;

}  

How do I get the totalNumber to show in the view?

I assume after I get this, in order to sum up my factory data:

var revenues = [
            { amount: 1254 },
            { amount: 1654 },
            { amount: 33 },
            { amount: 543 }

    ];

I will have to do something like:

 $scope.total = function() {
 var totalNumber = 0;
    for(i=0; i<revenues.length; i++){
      totalNumber = totalNumber + revenues[i].amount
    }

    }  

Is this correct? Will it update in real time if I dynamically change the revenue array?

3
  • You need to bind the variable to the scope. $scope.totalNumber = 0. Commented Oct 21, 2013 at 9:54
  • 2
    whatever the definition of total() you'll be able to display its value by simply doing {{ total() }} Commented Oct 21, 2013 at 9:54
  • @whirlwin doesn't work.. shows nothing, and if I add var it throws an error Commented Oct 21, 2013 at 9:59

3 Answers 3

8

As promised, here is a different approach. One that watches the revenues collection and updates a value every time it changes:

<div ng-app ng-controller="SumCtrl">

  Total: {{total}}

  <input type="text" ng-model="newAmount" />
  <button ng-click="add(newAmount)">Add</button>

</div>

And the JavaScript:

function SumCtrl($scope) {

  function total() {
    var totalNumber = 0;
    for(var i=0; i<$scope.revenues.length; i++){
      totalNumber = totalNumber + $scope.revenues[i].amount
    }

    return totalNumber;
  }

  $scope.revenues = [
    { amount: 1254 },
    { amount: 1654 },
    { amount: 33 },
    { amount: 543 }
  ];

  $scope.add = function(value) {
    $scope.revenues.push({ amount: parseInt(value) });
  }

  $scope.$watchCollection("revenues", function() {
    $scope.total = total();
  });

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

5 Comments

This looks like a great solution, however I can't get the $watchCollection method to work. I assume this might be my factory problem? Code: plnkr.co/edit/iDmphw
Which version of Angular are you using? I think that $watchCollection is a new thing. It is in 1.2rc3. I don't think it is 1.0.8. If $watchCollection isn't available, you can use $watch with the "deep" flag set to true (though $watchCollection is better). $watch("revenues", function(){}, true);
You are right. I need to update my version! (I am using a gem with Rails). Thank you for helping me out very much, maybe one day I will be as a smart Angular user as you are! :D
BTW: the total() function could be shortend to: return $scope.revenues.reduce(function(prev, cur) { return prev + cur.amount; }, 0);
@yankee Agreed. Assuming, at least, that reduce is defined. You'd need to polyfill for <IE9.
0

There are several approaches to solving this. If you want a total() function, it goes like this:

<div ng-app ng-controller="SumCtrl">

  Total: {{total()}}

  <input type="text" ng-model="newAmount" />
  <button ng-click="add(newAmount)">Add</button>

</div>

And here is the code:

function SumCtrl($scope) {

  $scope.revenues = [
    { amount: 1254 },
    { amount: 1654 },
    { amount: 33 },
    { amount: 543 }
  ];

  $scope.total = function() {
    var totalNumber = 0;
    for(var i=0; i<$scope.revenues.length; i++){
      totalNumber = totalNumber + $scope.revenues[i].amount
    }

    return totalNumber;
  }

  $scope.add = function(value) {
    $scope.revenues.push({ amount: parseInt(value) });
  }

}

The total() function will re-evaluate whenever the scope changes (a lot). A better approach is to watch for changes to revenues and update a static value... I'll post that answer as well.

Comments

0

Here's a plunker

There's more than one way to do this, and your controller might look different depending on how the data looks from your factory.

Edit: A couple of good answers were posted here while I was writing. This is similar to Brian's first approach.

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.