Search code examples
javascriptjsonjstreetraversaltree-traversal

Traverse JSON object to create jsTree


I want to create a jsTree from JSON with different depth (could be 10 or more levels). So I searched the web and found a method to create the jsTree: traversing.

Example JSON:

{
    "testslave_1": {
        "DevKey": "94ssfsafafeaw382",
        "mapping": {
            "device1": "D1",
            "device2": "D2",
            "device3": "D3"
        }
    }
}

Lucky for me there is traverse-js but I have problems with it.

This is the syntax required by jsTree:

$('#using_json_2').jstree({ 'core' : {
    'data' : [
       { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" },
       { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" },
       { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },
       { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" },
    ]
} });

I have tried this so far:

var obj = '{    "testslave_1": {        "DevKey": "94ssfsafafeaw382",       "mapping": {            "device1": "D1",            "device2": "D2",            "device3": "D3"     }   }}';

    var obj = JSON.parse(obj);
    var arr = [];

    traverse(obj).map(function (x) {
        
    var jsonTemp = '{ "id" : "'+this.path+'", "parent" : "'+this.parent+'", "text" : "'+this.node+'" }';
    jsonTemp = JSON.parse(jsonTemp);
    arr.push(jsonTemp);
        
    });

    console.dir(arr);

But there are serveral problems: How to create an specific ID for each item? (the function may remember the id for the parent-attribute)

It says object object, if I understand it in the right way I have to access the node of the parent object. But how? this.parent.node does not work.

There are items missing, it should be around 10 items.

Is my way of the solution going in the right direction?

Thank you in advance.


Solution

  • I have no idea of traverse-js. If you want to get some kind of tree structure like the example you can achieve that with a recursive function, for example like this one:

    var testobj = {
        testslave_1:{
            DevKey: "94ssfsafafeaw382",
            mapping: {
                device1:"D1",
                device2:"D2",
                device3:"D3"
            }
        }
    };
    var tree = {
        core: {
            data: []
        }
    };
    function createTreeData(object, parent){
        if(!parent){
            parent = "#"
        }
        for(var prop in object){
            if(object.hasOwnProperty(prop)){
                var obj = {
                    id: prop,
                    parent: parent
                };
                if(typeof object[prop] === "object"){
                    createTreeData(object[prop], prop);
                    obj.text = "parent node";
                }else{
                    obj.text = object[prop];
                }
                tree.core.data.push(obj);
            }
        }
    }
    createTreeData(testobj);
    console.log(tree);
    

    The only thing which this function doesn't provide is text for the elements which are parentNodes themselves. Instead it puts in the child objects which is most likely wrong. But you didn't specify what text parent nodes should contain.

    EDIT: I changed the function so that parent nodes now contain the text "parent node" rather than their child object.

    EDIT2: New function which makes nodes for properties which are just text:

    function createTreeData(object, parent){
        if(!parent){
            parent = "#"
        }
        for(var prop in object){
            if(object.hasOwnProperty(prop)){
                tree.core.data.push({
                    id: prop,
                    parent: parent,
                    text: prop
                });
                if(typeof object[prop] === "object"){
                    createTreeData(object[prop], prop);
                }else{
                    tree.core.data.push({
                        id: object[prop],
                        parent: prop,
                        text: object[prop]
                    });
                }
            }
        }
    }