You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
Repository navigation
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
$evalAsync does not always get executed in the current $digest cycle (1.0.0rc8) #947
Hi,
when I have a scope that contains a single $watch, which uses $evalAsync, then the $evalAsync does not get executed until the next $digest cycle, but not in the current $digest cycle.
When you type a character into the textbox, the $watch fires and logs the current value using $evalAsync to the console.
However, in this case, the value that is logged is not the current value of the input field, but the last value (e.g. type in "aaa", then the log only shows "aa".
A button increments a value on the $scope.
And there is a watcher on the $scope using a function as expression ($watch(function()...), which outputs the current value using $evalAsync to the console.
When you click the button to increment the counter, the $evalAsync is no more executed in the same $digest.
Tobias
Everything works if you:
Remove the <div ng-controller="EmptyCtrl">
Use a $watch(counter, ...) instead of a $watch(function())
Put a <input type="text" ng-model="counter"> in the html
this is not a bug. eval async does get executed, at the correct time, but the value you print is stale because it's a copy of the counter that is done in the watch fn.
I'm actually happy that your example doesn't blow up - at first look I would expect it to fail with infinite digest error.
The problem with your code is that your watch fn is not idempotent. The side-effect it has is the $evalAsync registration. This is a programming/design error in your code. Does your app suffer from the same issue or is there something else going on?
Sorry for the late reply.
I didn't know that the watch function is not allowed to have side effects. I read the source code of ng-repeat, which does all of the repeating logic in a watch function...
Activity
tbosch commentedon May 9, 2012
Sorry, this example is not right: It shows the old value because I use the wrong argument from the watch callback...
tbosch commentedon May 9, 2012
Ok, here is a better example: http://jsfiddle.net/GGbzx/3/
A button increments a value on the $scope.
And there is a watcher on the $scope using a function as expression ($watch(function()...), which outputs the current value using $evalAsync to the console.
When you click the button to increment the counter, the $evalAsync is no more executed in the same $digest.
Tobias
Everything works if you:
<div ng-controller="EmptyCtrl">$watch(counter, ...)instead of a$watch(function())<input type="text" ng-model="counter">in the htmlTobias
IgorMinar commentedon May 9, 2012
right the first fiddle incorrectly interpreted the order of arguments in the watch callback: http://jsfiddle.net/IgorMinar/GGbzx/4/
I'm looking at the second fiddle now
IgorMinar commentedon May 9, 2012
this is not a bug. eval async does get executed, at the correct time, but the value you print is stale because it's a copy of the counter that is done in the watch fn.
IgorMinar commentedon May 9, 2012
I'm actually happy that your example doesn't blow up - at first look I would expect it to fail with infinite digest error.
The problem with your code is that your watch fn is not idempotent. The side-effect it has is the $evalAsync registration. This is a programming/design error in your code. Does your app suffer from the same issue or is there something else going on?
IgorMinar commentedon May 9, 2012
I'm going close this bug. If you can repro it with idempotent watch fn then I'll be happy to reopen it and investigate further.
tbosch commentedon May 29, 2012
Sorry for the late reply.
I didn't know that the watch function is not allowed to have side effects. I read the source code of ng-repeat, which does all of the repeating logic in a watch function...
Thanks for investigating this.
Tobias