Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Passing in an a function to the ngOptions array clause that generates elements on the fly results in infinite $digest loop #9464

Closed

Description

@drjokepu

AngularJS 1.2.22 (in particular, commit c286094) has changed the behaviour of ngOptions from deep watching to shallow watching the elements of the array. If the array and its elements are generated by a function on the fly, shallow watching will fail as even if the elements are identical, they are separate instances. This results in infinite $digest loops:

    Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
    Watchers fired in the last 5 iterations: [["fn: $watchCollectionWatch; newVal: 37; oldVal: 32"],["fn: $watchCollectionWatch; newVal: 42; oldVal: 37"],["fn: $watchCollectionWatch; newVal: 47; oldVal: 42"],["fn: $watchCollectionWatch; newVal: 52; oldVal: 47"],["fn: $watchCollectionWatch; newVal: 57; oldVal: 52"]]
    http://errors.angularjs.org/"NG_VERSION_FULL"/$rootScope/infdig?p0=10&p1=%5B%5B%22fn%3A%20%24watchCollectionWatch%3B%20newVal%3A%2037%3B%20oldVal%3A%2032%22%5D%2C%5B%22fn%3A%20%24watchCollectionWatch%3B%20newVal%3A%2042%3B%20oldVal%3A%2037%22%5D%2C%5B%22fn%3A%20%24watchCollectionWatch%3B%20newVal%3A%2047%3B%20oldVal%3A%2042%22%5D%2C%5B%22fn%3A%20%24watchCollectionWatch%3B%20newVal%3A%2052%3B%20oldVal%3A%2047%22%5D%2C%5B%22fn%3A%20%24watchCollectionWatch%3B%20newVal%3A%2057%3B%20oldVal%3A%2052%22%5D%5D
        at /Users/tamas/build/github.com/drjokepu/angular.js/src/minErr.js:73:12
        at Scope.$digest (/Users/tamas/build/github.com/drjokepu/angular.js/src/ng/rootScope.js:705:19)
        at Scope.$apply (/Users/tamas/build/github.com/drjokepu/angular.js/src/ng/rootScope.js:931:24)
        at null.<anonymous> (/Users/tamas/build/github.com/drjokepu/angular.js/test/ng/directive/selectSpec.js:1142:15)

A tracking expression clause is supported by ngOptions that explicitly defines the expression that is used for comparing array elements. However, currently this is only used for identifying the selected item and not used for watching the elements of the array itself. I am suggesting extending the usage of this expression to be also used for differentiating of the array items themselves when shallow watching.

Reproducible: always
Browsers: Tested on Chrome 37, Safari 7.1
Operating System: OS X 10.9.5

Steps to reproduce:

  • Create a new html file and add the following content:
<!DOCTYPE html>
<html>
<head>
  <title>Infinite Digest</title>
</head>
<body>
  <body ng-app="demoApp">
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
    <script type='text/javascript'>
    angular.module('demoApp', []).controller('DemoController', function($scope) {
      $scope.makeOptions = function() {
          var options = [];
          for (var i = 0; i < 5; i++) {
              options.push({ label: 'Value = ' + i, value: i });
          }
          return options;
      };
      $scope.selected = { label: 'Value = 1', value: 1 };
    });
    </script>
    <div ng-controller="DemoController">
        <div>
            <h2>Infinite Digest</h2>
            <select ng-model="selected"
                ng-options="opt as opt.label for opt in makeOptions() track by opt.value">
            </select>
            The value selected is {{ selected.value }}.
        </div>
    </div>
</body>
</body>
</html>
  • Open this file in a browser. AngularJS will report infinite digest in the console.

This works fine on AngularJS 1.2.21 and earlier.

I am not really an Angular developer (or a real JavaScript developer for that matter), but I am going to submit a pull request with a spec test as well as a proposed solution that will illustrate how I would go about tackling the issue,

Activity

  1. caitp commented on Oct 7, 2014

    @caitp
    Contributor

    #9419 may be partially related to what you want (since currently tracking expressions don't really work at all)

  2. added this to the milestone on Oct 7, 2014
  3. added 3 commits that reference this issue on Oct 7, 2014
    476c877
    e3ca351
    f425223
  4. drjokepu commented on Oct 7, 2014

    @drjokepu
    Author

    Yes, I forgot that I was working on 1.2.26 and not master, rookie mistake, thanks a lot!

  5. added a commit that references this issue on Jan 11, 2015
    6070d5b
  6. petebacondarwin commented on Jan 11, 2015

    @petebacondarwin
    Contributor
  7. added a commit that references this issue on Jan 12, 2015
    4725ddb
  8. ipoly commented on May 12, 2015

    @ipoly

    @petebacondarwin I just try the plunker demo with 1.3.15 and find that it still throw infdig errors.

  9. Narretz commented on Jun 5, 2015

    @Narretz
    Contributor

    @ipoly the fix is only available in the 1.4.x branch

  10. Jerryzhao-z commented on Oct 18, 2016

    @Jerryzhao-z

    @petebacondarwin the plunker demo doesn't work anymore, and I have the same issue of ngOptions

  11. gkalpak commented on Oct 18, 2016

    @gkalpak
    Member

    @Jerryzhao-z, it is probably because that CI build artifacts are not available any more. Here is the same plnkr using v1.5.8: http://plnkr.co/edit/krNb7CjrQ55i1LeOTJ91?p=preview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions