Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maxing out on $digest iterations

Tags:

angularjs

I'm playing around with directives and = binding in this fiddle. I'm getting the following error:

Uncaught Error: 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["fn: function () {\n                  var parentValue = parentGet(parentScope);\n\n                  if (parentValue !== scope[scopeName]) {\n                    // we are out of sync and need to copy\n                    if (parentValue !== lastValue) {\n                      // parent changed and it has precedence\n                      lastValue = scope[scopeName] = parentValue;\n                    } else {\n                      // if the parent can be assigned then do so\n                      parentSet(parentScope, lastValue = scope[scopeName]);\n                    }\n                  }\n                  return parentValue;\n                }; newVal: {\"baz\":3}; oldVal: {\"baz\":3}"],["fn: function () {\n                  var parentValue = parentGet(parentScope);\n\n                  if (parentValue !== scope[scopeName]) {\n                    // we are out of sync and need to copy\n                    if (parentValue !== lastValue) {\n                      // parent changed and it has precedence\n                      lastValue = scope[scopeName] = parentValue;\n                    } else {\n                      // if the parent can be assigned then do so\n                      parentSet(parentScope, lastValue = scope[scopeName]);\n                    }\n                  }\n                  return parentValue;\n                }; newVal: {\"baz\":3}; oldVal: {\"baz\":3}"],["fn: function () {\n                  var parentValue = parentGet(parentScope);\n\n                  if (parentValue !== scope[scopeName]) {\n                    // we are out of sync and need to copy\n                    if (parentValue !== lastValue) {\n                      // parent changed and it has precedence\n                      lastValue = scope[scopeName] = parentValue;\n                    } else {\n                      // if the parent can be assigned then do so\n                      parentSet(parentScope, lastValue = scope[scopeName]);\n                    }\n                  }\n                  return parentValue;\n                }; newVal: {\"baz\":3}; oldVal: {\"baz\":3}"],["fn: function () {\n                  var parentValue = parentGet(parentScope);\n\n                  if (parentValue !== scope[scopeName]) {\n                    // we are out of sync and need to copy\n                    if (parentValue !== lastValue) {\n                      // parent changed and it has precedence\n                      lastValue = scope[scopeName] = parentValue;\n                    } else {\n                      // if the parent can be assigned then do so\n                      parentSet(parentScope, lastValue = scope[scopeName]);\n                    }\n                  }\n                  return parentValue;\n                }; newVal: {\"baz\":3}; oldVal: {\"baz\":3}"],["fn: function () {\n                  var parentValue = parentGet(parentScope);\n\n                  if (parentValue !== scope[scopeName]) {\n                    // we are out of sync and need to copy\n                    if (parentValue !== lastValue) {\n                      // parent changed and it has precedence\n                      lastValue = scope[scopeName] = parentValue;\n                    } else {\n                      // if the parent can be assigned then do so\n                      parentSet(parentScope, lastValue = scope[scopeName]);\n                    }\n                  }\n                  return parentValue;\n                }; newVal: {\"baz\":3}; oldVal: {\"baz\":3}"]] angular.js:7729
Scope.$digest angular.js:7729
Scope.$apply angular.js:7894
(anonymous function) angular.js:930
invoke angular.js:2788
bootstrap angular.js:928
angularInit angular.js:904
(anonymous function) angular.js:14397
trigger angular.js:1695
(anonymous function) angular.js:1930
forEach angular.js:110
eventHandler angular.js:1929

Why is this happening? I think it has something to do with the = binding.

like image 367
Nick Heiner Avatar asked Nov 27 '12 22:11

Nick Heiner


1 Answers

This is because it is is creating a brand new object every time it goes through the digest cycle. Watches are registered in this = databinding, and so every time it evaluates bar="{baz: 3}" a new object is created, and so it will be different from the previous value, trigerring another digest loop. Eventually it aborts so that it doesn't loop infinitely. See http://docs.angularjs.org/guide/concepts#runtime for a more thorough explanation.

The trick is to do the = databing with a reference that won't be changing every time. This is usually done by having it in the scope outside the directive. See http://jsfiddle.net/u4BTu/7/

like image 123
dnc253 Avatar answered Nov 13 '22 19:11

dnc253