Search code examples
javascriptjqueryjstree

Jstree: Cannot read property children of undefined. Timing issue?


I have an array of objects where each of them look like this structure:

var data = [{
"code" : "i1",
"name" : "Industry 1",
"parentCode" : "i0"
}, 
{
//and more items just like that one
}];

so I am using jstree to build a hierarchy view. Since jstree needs id and text, I map the data array like this:

datatree = $.map(data, function (item) {

        return {
            id : item.code,
            text : item.name,
            parent : item.parentCode

        };

    });

And then I initialize the actual tree inside my hierarchy div:

$('#hierarchy').jstree({

    "core": {
        "themes": {
            "variant": "large"
        },
        "data": datatree,
    },
    'check_callback': true,
    "checkbox": {
        "keep_selected_style": false
    },
    "plugins": ["wholerow", "search", "unique"]
});

This builds the tree and works fine when the original array is pretty simple, maybe one or two levels deep of parentages. However, if I test with an alternative array build exactly the same way, but with 5 levels of parentages, the console throws an error:

Uncaught TypeError: Cannot read property 'children' of undefined

And it's pointing to this row in the jstree original code:

k[c[o].parent.toString()].children.push(c[o].id.toString()),

I have the suspicion that it's a timing issue, as in jstree being unable to build the children array because there are still pending items to load. But I might be wrong in my assumption.

How can it be that the code works perfectly for arrays with simple parentages, but it breaks when there are multiple parent levels? Is it just timing as I guess, or there might be deeper issues?

I have read this question, but it seems that the user was initially working with AJAX and solved the problem declaring a local object. Mine is already local and it actually works in some cases, so I am not sure what's going on.


Solution

  • That error happens with me when, in your code:

    {
      id : item.code,
      text : item.name,
      parent : item.parentCode
    };
    

    Your parent has an id of to a non-existent item. The parent key must exist, and won't accept false, null, 0, or an id that isn't in the data list. If an item has no parent, the parent needs to be "#", i.e. "parent": "#".

    So:

    • Check items with parent null or undefined;
    • Check items with parent without corresponding parent