Removing watches from inside a watch can cause dirty watches to be skipped (regression) #5525
Description
Due to recent changes that added optimization in the digest function with lastDirtyWatch
if(watch === lastDirtyWatch) {....}
#5287
The scenario
during digest , one watch was called that caused a second watch to be removed. The first watch had an index which was larger then the second watch in the watchers array so the remove shifted all the indexes to the left , and the next iteration when getting length--; watchers[length] it will return the previous watch that was already called and so the condition watch === lastDirtyWatch will be true and it breaks from the loop and miss calls to the remaining watches in the array (some which have also changed)
one option to solve this is to nullify lastDirtyWatch in the unregister function that is returned from $watch
return function() {
arrayRemove(array, watcher);
lastDirtyWatch = null;
};
other is to defer the removal of the watcher till after the digest loop .