angular-bootstrap-nav-tree icon indicating copy to clipboard operation
angular-bootstrap-nav-tree copied to clipboard

Angular 1.3 Support: Duplicates in a repeater not allowed Error.

Open atapas opened this issue 9 years ago • 2 comments

I am using the nav-tree along with AngularJS 1.3.

My tree data is as simple as:

$scope.my_data = [{ label: 'Languages', children: ['Jade','Less','Coffeescript'] }];

Error is:

Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: row in tree_rows | filter:{visible:true} track by row.branch.uid, Duplicate key: undefined, Duplicate value: {"level":2,"branch":{"label":"Less","children":[],"expanded":false,"classes":["leaf"]},"label":"Less","classes":"<>","tree_icon":"icon-file glyphicon glyphicon-file fa fa-file","visible":true} http://errors.angularjs.org/1.3.15/ngRepeat/dupes?p0=row%20in%20tree_rows%2…0glyphicon%20glyphicon-file%20%20fa%20fa-file%22%2C%22visible%22%3Atrue%7D at REGEX_STRING_REGEXP (main.js:9268) at ngRepeatAction (main.js:33836) at Object.$watchCollectionAction as fn at Scope.$get.Scope.$digest (main.js:23513) at Scope.$get.Scope.$apply (main.js:23776) at done (main.js:18903) at completeRequest (main.js:19093) at XMLHttpRequest.requestLoaded (main.js:19034)

Same code works with Angular 1.2.

I think this is because, Duplicate keys are banned in AngularJS as it uses keys to associate DOM nodes with items.

However the following data works well without error:

$scope.my_data = [ { label: 'Animal', children: [ { label: 'Dog', data: { description: "man's best friend" } }, { label: 'Cat', data: { description: "Felis catus" } }, { label: 'Hippopotamus', data: { description: "hungry, hungry" } }, ] }];

atapas avatar Apr 10 '15 18:04 atapas

I had the same error with the same data, and also using angular 1.3.

The error message shows the duplicate value as:

{
    "level":2,
    "branch":{
        "label":"Less",
        "children":[],
        "expanded":false,
        "classes":["leaf"]
        },
    "label":"Less",
    "classes":"<<already seen>>",
    "tree_icon":"icon-file  glyphicon glyphicon-file  fa fa-file",
    "visible":true
}

but if you look at tree_rows, the object is:

{
    "level":2,
    "branch": {
        "label":"Less",
        "children":[],
        "expanded":false,
        "classes":["leaf"],
        "uid": "0.9719345979392529",
        "parent_uid": "0.6194524599704891"
    },
    "label":"Less",
    "classes":["leaf"],
    "tree_icon":"icon-file glyphicon glyphicon-file fa fa-file",
    "visible":true
}

..so ng-repeat is seeing a version of the object which is missing branch.uid and branch.parent_uid and it's tracking by object.classes (notice <> tag in the error message).

The problem goes away when you change the child array from strings to simple objects of format { label: "Less" }.

RichardMatsen avatar May 26 '15 19:05 RichardMatsen

On further investigation I found that the compiled javascript doesn't match the source abn_tree_directive.coffee.

In the coffeescript file, the order of things is

      # if "children" is just a list of strings...
      # ...change them into objects:

      # give each Branch a UID ( to keep AngularJS happy )

In the javascript version, it's the other way around. Moving the uid assignment block below fixes the problem.

I guess it just needs the grunt file to be run and the code recommitted to git.

RichardMatsen avatar May 26 '15 22:05 RichardMatsen