nickperkinslondon / angular-bootstrap-nav-tree

An AngularJS directive that creates a Tree based on a Bootstrap "nav" list.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

atapas opened this issue · 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"
}
},
]
}];

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" }.

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.