0

I am trying to turn the json data that is in the db variable into a nested list on the html page. Instead it is giving me a sort of ladder of each child node inserted into the child node before it. I can not figure out why it is not nesting correctly. What am i missing?

db = JSON.parse(`
                {
                    "title": "Root", 
                    "children": [
                        {
                            "title": "Child1",
                            "children": [
                                {"title": "Child1a"},
                                {"title": "Child1b"},
                                {"title": "Child1c"}
                            ]
                        },
                        {
                            "title": "Child2",
                            "children": [
                                {"title": "Child2a"},
                                {"title": "Child2b"},
                                {"title": "Child2c"}
                            ]
                        }
                    ]
                }
            `);

function recurse(u, j) {

  li = document.createElement('li');
  ul = document.createElement('ul');

  li.setAttribute('title', j.title);

  li.appendChild(ul);
  u.appendChild(li);

  (j.children || []).forEach(c => {
    recurse(ul, c);
  });

}

recurse(document.getElementById('tree'), db);
* {
  margin: 0;
}

li::before {
  content: attr(title);
}

li:hover {
  cursor: grab;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Scratch</title>
</head>

<body>
  <ul id='tree'></ul>
</body>

</html>

7
  • 4
    Declare your variables local to the function with let. Commented Nov 23, 2021 at 20:06
  • Otherwise they're global variables, and when you recurse you overwrite the variables used in the caller. Commented Nov 23, 2021 at 20:06
  • 2
    Always declare your variables. Commented Nov 23, 2021 at 20:07
  • wow thank you! I was not aware that javascript did this. Commented Nov 23, 2021 at 20:08
  • 1
    @pilchard It's not a typo. But reproducible and exemplary :) Commented Nov 23, 2021 at 20:15

1 Answer 1

2

You're referring to the same variables over and over because you're not re-declaring them in the function scope.

db = JSON.parse(`
                {
                    "title": "Root", 
                    "children": [
                        {
                            "title": "Child1",
                            "children": [
                                {"title": "Child1a"},
                                {"title": "Child1b"},
                                {"title": "Child1c"}
                            ]
                        },
                        {
                            "title": "Child2",
                            "children": [
                                {"title": "Child2a"},
                                {"title": "Child2b"},
                                {"title": "Child2c"}
                            ]
                        }
                    ]
                }
            `);

function recurse(u, j) {

  var li = document.createElement('li');
  var ul = document.createElement('ul');

  li.setAttribute('title', j.title);

  li.appendChild(ul);
  u.appendChild(li);

  (j.children || []).forEach(c => {
    recurse(ul, c);
  });

}

recurse(document.getElementById('tree'), db);
* {
  margin: 0;
}

li::before {
  content: attr(title);
}

li:hover {
  cursor: grab;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Scratch</title>
</head>

<body>
  <ul id='tree'></ul>
</body>

</html>

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, you don't need let for this. The good old var is just sufficient most of the times.
@Redu thank you. yea i tried both and they worked currently googling the difference between the two.
I typically only use let when declaring a variable in a loop or a block scope and i know i won't need it after the loop or block.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.