3

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.

4
  • That is weird. Here's a fiddle with the same code as in your question plus a couple of console.log() statements: jsfiddle.net/6VqqN/2. Looks like update1() gets called four times (like you'd expect), but update2() gets called repeatedly until Angular crashes. Commented Oct 30, 2013 at 8:42
  • P.S. It looks like the same problem occurs with both controls if the first {{update()}} call passes a non-zero value, but the problem does not occur with either controller if the first value is zero. (I don't know why, but maybe that helps somebody else explain it.) Commented Oct 30, 2013 at 8:54
  • Yes Yes, Im not claiming it is not happening in the first controller, I used two controllers for better explanation Commented Oct 30, 2013 at 9:17
  • I think both controllers are getting called too many times. In case of Controller1 value of x is returned to 0. And that is why the effect is not visible. The question is why are they getting called too many times? Commented Oct 30, 2013 at 9:19

2 Answers 2

2

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..

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

1 Comment

No problem;). I'm also new to angular, and am very fascinated with it. I'm also new to stackoverflow, and I think the best "thank you" here would be sign as "the best answer" to your question :D peace! and good luck for you and all angular guys
0

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.

3 Comments

Yes, I understood a little. Thanks for your reply. So What should I do to achive the desired output. Is there anyway to update in the expression itself like {{x=x+25}} like that?
A guy called Pasvas wrote a solution for such case. You can use his solution from here: github.com/Pasvaz/bindonce Use it like so: <div bo-text="value"></div>, value will be displayed once it's available and not updated anymore.
Thanks Mr.Ephi Gabay, I'm looking at it :)

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.