Siva Kumar
Siva Kumar

Reputation: 725

Angularjs: addition of integers even after I parse the variable as integer

I really have a weird problem in adding two numbers.

Here is my code, in the first controller everything is working fine, but in the second controller instead of 0 if I add 10, the output is completely weird

Here is html code

<div ng-app="">
<div ng-controller="Controller1">
    <br/>**** Controller-1
    <br/>Add 0 : {{update1(0)}}
    <br/>Add 10 : {{update1(10)}}
    <br/>Add 50 : {{update1(50)}}
    <br/>Add -60 : {{update1(-60)}}</div>
<div ng-controller="Controller2">
    <br/>**** Controller-2
    <br/>Add 10 : {{update2(10)}}
    <br/>Add 10 : {{update2(10)}}
    <br/>Add 50 : {{update2(50)}}
    <br/>Add -60 : {{update2(-60)}}</div>
</div>

Here is my javascript

function Controller1($scope) {
var x = 0;
$scope.update1 = function (smValue) {
    x += parseInt(smValue);
    return x;
}
}

function Controller2($scope) {
var y = 0;
$scope.update2 = function (smValue) {
    y += parseInt(smValue);
    return y;
}
}

and here is the output

**** Controller-1 
Add 0 : 0 
Add 10 : 10 
Add 50 : 60 
Add -60 : 0

**** Controller-2 
Add 0 : 110 
Add 10 : 120 
Add 50 : 170 
Add -60 : 110

here is the link to try: http://jsfiddle.net/6VqqN/

can anyone please explain me why it is behaving like that. Even if I add a 3or4 digit number, output is completely different then what I expected.

Upvotes: 3

Views: 5592

Answers (2)

Arūnas Smaliukas
Arūnas Smaliukas

Reputation: 3321

I'll answer with a little bit different example.

This one works fine
1) http://jsfiddle.net/QThdE/1/

This one has the same problem as yours:
2) http://jsfiddle.net/SE5a3/1/

Both exmaples uses the same controller:

function MyController($scope){
    var x=parseInt(00);
    $scope.updateX = function(smValue){
        x += parseInt(smValue);
    }
    $scope.printX = function() {
        return x;
    }
}

The magic is that both functions depends on x, and both functions waits for changes in this variable.

1) So in first case:

<div ng-app="" ng-controller="MyController" ng-init="updateX(5)">
    {{printX(0)}}
    <br/><a ng-click="updateX(10)">Click to increase by 10</a>
</div>

Everything works as expected, because updateX() is called only on init and click.

2) Second example has infinity loop like in your example:

<div ng-app="" ng-controller="MyController">
    {{printX(0)}}
    {{updateX(5)}}
    <br/><a ng-click="updateX(10)">Click to increase by 10</a>
</div>

Why? lets look how angular compiles this view:

1) {{printX(0)}} - prints current x value and waits for someone touching x
2) {{updateX(5)}} - updates x value, and as it also depends on x, it also waits for someone touching x
3) {{printX(0)}} - as step 2) changed x value, this functions calls again and prints x value (and in same time touches x value)
4) {{updateX(5)}} - as step 3) touched x value, this functions calls again..
5) etc.

The same with your example:

<br/>Add 10 : {{update2(10)}}
<br/>Add 10 : {{update2(10)}}

first time you call update2(10) it adds 10 to x, and waits for x changes. Second time you call it, you change x value again, and that causes to call first function again, after that second calls again, and so on..

Upvotes: 2

Ephi Gabay
Ephi Gabay

Reputation: 938

When you bind to a function in AngularJS, it reevaluates the function each time one of the variables used the in the function change.
Since update1 and update2 change $scope.x, it cases the function to be reevaluated again and again in an infinite loop because $scope.x is used inside those functions.
Now, why isn't it happening in Controller1? It does, you just don't see it because at the end of each loop in Controller1 the value of $scope.x is returned to 0 (0 + 10 + 50 - 60 = 0), so no matter how many times you loop through those functions $scope.x would always be equal to the same values.
In controller2 the value of $scope.x is 10 at the end of each loop (0 + 10 + 10 + 50 - 60 = 10), so the value of $scope.x is raised by 10 after each loop. So if there is an infinite loop, why doesn't my browser freeze and still displays some values on controller2 also? Because AngularJS stop $digest loops after 10 iterations (that's why $scope.x is equal 10 at the beginning of the last iteration ($scope.x is raised by 10 after each iteration so 10 * 10 = 100).

Also, parseInt is redundant, because the variable you pass is already an integer.

Upvotes: 0

Related Questions