1

Considering JSON tree structure listed below (it can be n level deep), I want to create a nested unordered list

var data = [{
        'text': 'Subjects',
        'data': [{
            'text': 'Geography',
            'data': []
        }, {
            'text': 'History',
            'data': [{
                'text': 'Ancient History',
                'data': []
            }]
        }]
    }, {
        'text': 'Sports',
        'data': []
    }, {
        'text': 'Music',
        'data': []
    }];

data can be nested 'n' level deep. You can have 'data' within 'data' which is within another 'data' and so on.

The output should be something like this

<ul>
<li>Subjects
    <ul>
        <li>Geography</li>
        <li>History
            <ul>
                <li>Ancient History
                </li>
            </ul>
        </li>
    </ul>
</li>
<li>Sports
</li>
<li>Music
</li>

function json_tree(object) {
    var json = "<ul>";
    for (prop in object) {
        var value = object[prop];
        switch (typeof(value)) {
            case "object":
                json += "<li>" + value.text + json_tree(value) + "</li>";
                break;
            default:
                json += "<li>" + value.text + "</li>";
        }
    }
    return json + "</ul>";
}

I have tried using the above code, but this does not yield required results.

Raj
  • 65
  • 5
  • 5
    Not sure what you're asking. Please clarify, and tell us what you've tried and why it didn't work. – amphetamachine Aug 28 '14 at 15:44
  • 1
    What is the result you want to get? What have you tried so far? Where are you stuck? I'm inclined to close as duplicate of [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Felix Kling Aug 28 '14 at 15:47
  • 1
    *"I have tried using the above code, but this does not yield required results."* Which result do you get? – Felix Kling Aug 28 '14 at 16:22

1 Answers1

1

Your current logic will find the following keys in the for...in loop:

0
'text'
'data'

Retrieving the text property of obj[0] works as expected, but:

obj['text'].text === undefined
obj['data'].text === undefined

which gives you the bad results you are seeing (jsFiddle):

Subjects
    undefined
    undefined
        Geography
            undefined
            undefined
        History
            undefined
            undefined
            Ancient History
                undefined
                undefined
Sports
    undefined
    undefined
Music
    undefined
    undefined

I've change the iterator to use a simple for loop rather than for...in.

Additionally, you can simplify the checks to just look for the length of data at the currently indexed object to determine if you need to recurse into json_tree again:

function json_tree(data) {
    var json = "<ul>";

    for(var i = 0; i < data.length; ++i) {
        json = json + "<li>" + data[i].text;
        if(data[i].data.length) {
            json = json + json_tree(data[i].data);
        }
        json = json + "</li>";
    }
    return json + "</ul>";
}

demo fiddle

dc5
  • 12,341
  • 2
  • 35
  • 47