0

I've written a codepen to better explain my confusion on angular scope.

From the below script, I have a starting balance of 20000, i want to display the change in balance once a new transaction has been recorded, however, i get this weird result which I can't explain. Can anyone please help? What did I do wrong?

Thanks in advance!

var transactionApp = angular.module('transactionApp', []);

transactionApp.controller("transactionCtrl", ['$scope',
  function($scope) {
    $scope.transactions = [100, -200, 500, 10000, -2000];
    $scope.balance = 20000;
    $scope.updateBalance = function(balance, transaction) {
      $scope.balance += transaction;
      return $scope.balance;
    }
  }
])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="transactionApp">
  <div ng-controller="transactionCtrl">
    Current Balance: {{balance}}
    <br/>Transaction history:
    <ul>
      <li ng-repeat="transaction in transactions">
        Transaction:{{transaction}}
        <br/>Balance: {{updateBalance(balance, transaction)}}
      </li>
    </ul>
  </div>
</div>
led
  • 1,544
  • 5
  • 17
  • 23

2 Answers2

1

The issue is due the function updateBalance in the view. It gets called with Angular runs its digest cycle. The digest cycle goes through and updates/runs any variables/functions within the '{{}}' anytime those variables change values. In this case, it's running your updateBalance function many times due to the balance variable changing.

To fix the current issue you're having. I'd move the update balances to a button. On click of the button run the updateBalance function. Or take the update balance out of your view altogether and use it within your controller, iterate over the transactions and manually subtract the values from your balance.

Hope that helped. :)

Here's another question regarding the digest cycle: when $digest cycle is called?

Update (Fixing logic as requested):

var transactionApp = angular.module('transactionApp', []);

transactionApp.controller("transactionCtrl", ['$scope',
  function($scope) {
    $scope.transactions = [100, -200, 500, 10000, -2000];
    $scope.balance = 20000;

    $scope.getBalanceAfterTransaction = function(transaction){
       $scope.balance += transaction
       return $scope.balance;
    }
  }
])


<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="transactionApp">
  <div ng-controller="transactionCtrl">
    Current Balance: {{balance}}
    <br/>Transaction history:
    <ul>
      <li ng-repeat="transaction in transactions">
        Transaction:{{transaction}}
        <br/>Balance: {{getBalanceAfterTransaction(transaction)}}
      </li>
    </ul>
  </div>
</div>

Let me know if you need anymore clarification :)

Community
  • 1
  • 1
matt
  • 1,680
  • 1
  • 13
  • 16
1

basically an example of what @Treeless mentioned. plnkr

$scope.clickBalance = function(transaction) {
  return $scope.balance += transaction;
};
4UmNinja
  • 510
  • 4
  • 14