Reputation: 725
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
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
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