Cannot display JSON in HTML using JavaScript

I’m having issues getting my nested JSON to appear in my HTML. Can someone help?

const data = {
    "layers": [{
            "order": 0,
            "items": [{
                    "order": 2,
                    "name": "Randomly Generous Red",
                    "imgSrc": "jeb.png"
                },

                {
                    "order": 1,
                    "name": "Too Agreeable Silver",
                    "imgSrc": "VRC.png"
                },

                {
                    "order": 3,
                    "name": "Almost Whispy Blue",
                    "imgSrc": "58Z.png"
                },

                {
                    "order": 0,
                    "name": "Some Times Juicy Red",
                    "imgSrc": "081.png"
                }
            ]
        },

        {
            "order": 1,
            "items": [{
                    "order": 0,
                    "name": "Never Substantial Silver",
                    "imgSrc": "BWK.jpg"
                },

                {
                    "order": 1,
                    "name": "Really Adorable Pink",
                    "imgSrc": "hk9.jpg"
                }
            ]
        },

        {
            "order": 2,
            "items": [{
                    "order": 2,
                    "name": "Very Honest Black",
                    "imgSrc": "0Og.png"
                },

                {
                    "order": 4,
                    "name": "Never Eager Red",
                    "imgSrc": "2Ks.png"
                },

                {
                    "order": 0,
                    "name": "Kind Of Adorable Silver",
                    "imgSrc": "L99.png"
                },

                {
                    "order": 3,
                    "name": "Some Times Confident Pink",
                    "imgSrc": "Wx4.png"
                },

                {
                    "order": 1,
                    "name": "Never Brave Blue",
                    "imgSrc": "020.png"
                }
            ]
        }
    ],
    "default_configuration": [
        0,
        1,
        4
    ]
};


const sorted = {
  'layers': data.layers
                .sort(({ order: a }, { order: b}) => a - b)
                .map(o => { 
                  o.items.sort(({ order: a }, { order: b}) => a - b);
                  return o;
                }),
  'default_configuration': data.default_configuration
};

console.log(sorted);

The JavaScript I’ve tried is:

fetch('url')
  .then(function (response) {
    return response.json();
  })
.then(function(data) {
      appendData(data);
    })
  .catch(function (err) {
      console.log(err);
  });
    
function appendData(data) {
  var mainContainer = document.getElementById("myData");
  for (var i = 0; i < data.length; i++) {
    var div = document.createElement("div");
    div.innerHTML = 'Name: ' + data[i].order + ' ' + data[i].name;
    mainContainer.appendChild(div);
  }
}

Nothing shows in the HTML

1 Like

Can you share your filenames?

In there is the JSON file and the HTML file containing the JS

In your for loop, try accessing data['layers'][i] instead of just data[i]. Almost everything in your JSON appears to be in “layers”

You can’t access names that way, though. I think something like this may be what you’re looking for:

for (var i = 0; i < data['layers'].length; i++) {
        var whatYouTryToTraverse = data['layers'][i]['items']; //every one of these objects seems to have an item property which holds the data you are trying to access
     for(var j = 0; j < whatYouTryToTraverse.length; j++){
        var div = document.createElement("div");
        div.innerHTML = 'Name: ' + whatYouTryToTraverse[j].order + ' ' + whatYouTryToTraverse[j].name;
        mainContainer.appendChild(div);
    }
  }

I tested it; It works :grin:

You were trying to traverse the items property of your object, but you were traversing the data object itself. This will not work because the data object itself only has 2 properties: layers and default_configuration. You needed to access and traverse the items prooperties of each of the objects contained in the layers property

Did you test through Github? I’m trying but it’s spitting out a console error to do with CORS

I did not test in github, I improvised a bit because the fetch api was not working for me (I suspect you are using Node.js? I, meanwhile, am just using the chrome browser to test the JavaScript). Here’s the code I used:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JSON Test</title>
</head>
<body>
    <div id="myData"></div>
    <script>
        const data = {
    "layers": [{
            "order": 0,
            "items": [{
                    "order": 2,
                    "name": "Randomly Generous Red",
                    "imgSrc": "jeb.png"
                },

                {
                    "order": 1,
                    "name": "Too Agreeable Silver",
                    "imgSrc": "VRC.png"
                },

                {
                    "order": 3,
                    "name": "Almost Whispy Blue",
                    "imgSrc": "58Z.png"
                },

                {
                    "order": 0,
                    "name": "Some Times Juicy Red",
                    "imgSrc": "081.png"
                }
            ]
        },

        {
            "order": 1,
            "items": [{
                    "order": 0,
                    "name": "Never Substantial Silver",
                    "imgSrc": "BWK.jpg"
                },

                {
                    "order": 1,
                    "name": "Really Adorable Pink",
                    "imgSrc": "hk9.jpg"
                }
            ]
        },

        {
            "order": 2,
            "items": [{
                    "order": 2,
                    "name": "Very Honest Black",
                    "imgSrc": "0Og.png"
                },

                {
                    "order": 4,
                    "name": "Never Eager Red",
                    "imgSrc": "2Ks.png"
                },

                {
                    "order": 0,
                    "name": "Kind Of Adorable Silver",
                    "imgSrc": "L99.png"
                },

                {
                    "order": 3,
                    "name": "Some Times Confident Pink",
                    "imgSrc": "Wx4.png"
                },

                {
                    "order": 1,
                    "name": "Never Brave Blue",
                    "imgSrc": "020.png"
                }
            ]
        }
    ],
    "default_configuration": [
        0,
        1,
        4
    ]
};
        var mainContainer = document.getElementById("myData");
        for (var i = 0; i < data['layers'].length; i++) {
        var whatYouTryToTraverse = data['layers'][i]['items']; //every one of these objects seems to have an item property which holds the data you are trying to access
     for(var j = 0; j < whatYouTryToTraverse.length; j++){
        var div = document.createElement("div");
        div.innerHTML = 'Name: ' + whatYouTryToTraverse[j].order + ' ' + whatYouTryToTraverse[j].name;
        mainContainer.appendChild(div);
    }
  }
    </script>
</body>
</html>

yOutput

That’s the output I’m getting

It all working on my end, I’ve added the JS to sort it on load which is working perfectly fine. I was trying to get it to display using Vanilla JS I think.

Thanks so much for helping.

You’re welcome

(It won’t let me post only “you’re welcome” so I’m putting this as well)

If I have anything else I’ll come to you!

(Give it a day or two and I will aha)

:smile: I’m not an expert, but I’ll give it a shot

1 Like

Back once again. So what I’m trying to achieve is to create a clickable menu and submenu using the nested JSON. The expected output will be something like this:

<ul> A menu
<li>Order 0</li>
      <li>Product name in ordered format <li>
<li>Order 1</li>
      <li>Product name in ordered format <li>
<li>Order 2</li>
     <li>Product name in ordered format <li>
</ul>

You are very close with the previous solution. You just need to use the innerHtml property to create the <li> tags and whatnot. To make them clickable, you could add click events to them.

Managed to do that, time to just make it all clickable and produce an image with a prefixed URL

What does your code look like so far and what output are you looking to get?

At the moment my code looks like this

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" type="text/css" href="style.css">
    <title>Code Exercise</title>
</head>
<body>
    <div class="header">
        <div class="title">
            <h2>Code Test</h2>
        </div>
    </div>
    <div id="myData">
        <ul id="menu">Choose your furniture</ul>
    </div>
    <script>
        const data = {
    "layers": [{
            "order": 0,
            "items": [{
                    "order": 2,
                    "name": "Randomly Generous Red",
                    "imgSrc": "jeb.png"
                },

                {
                    "order": 1,
                    "name": "Too Agreeable Silver",
                    "imgSrc": "VRC.png"
                },

                {
                    "order": 3,
                    "name": "Almost Whispy Blue",
                    "imgSrc": "58Z.png"
                },

                {
                    "order": 0,
                    "name": "Some Times Juicy Red",
                    "imgSrc": "081.png"
                }
            ]
        },

        {
            "order": 1,
            "items": [{
                    "order": 0,
                    "name": "Never Substantial Silver",
                    "imgSrc": "BWK.jpg"
                },

                {
                    "order": 1,
                    "name": "Really Adorable Pink",
                    "imgSrc": "hk9.jpg"
                }
            ]
        },

        {
            "order": 2,
            "items": [{
                    "order": 2,
                    "name": "Very Honest Black",
                    "imgSrc": "0Og.png"
                },

                {
                    "order": 4,
                    "name": "Never Eager Red",
                    "imgSrc": "2Ks.png"
                },

                {
                    "order": 0,
                    "name": "Kind Of Adorable Silver",
                    "imgSrc": "L99.png"
                },

                {
                    "order": 3,
                    "name": "Some Times Confident Pink",
                    "imgSrc": "Wx4.png"
                },

                {
                    "order": 1,
                    "name": "Never Brave Blue",
                    "imgSrc": "020.png"
                }
            ]
        }
    ],
    "default_configuration": [
        0,
        1,
        4
    ]
};
        const sorted = {
  'layers': data.layers
                .sort(({ order: a }, { order: b}) => a - b)
                .map(o => { 
                  o.items.sort(({ order: a }, { order: b}) => a - b);
                  return o;
                }),
  'default_configuration': data.default_configuration
};
        
        var mainContainer = document.getElementById("myData");
        for (var i = 0; i < data['layers'].length; i++) {
        var whatYouTryToTraverse = data['layers'][i]['items']; //every one of these objects seems to have an item property which holds the data you are trying to access
     for(var j = 0; j < whatYouTryToTraverse.length; j++){
        var li = document.createElement("li");
        li.innerHTML = 'Order: ' + whatYouTryToTraverse[j].order + ' ' + whatYouTryToTraverse[j].name;
        mainContainer.appendChild(li);
         let element = document.getElementById('menu').appendChild(li);
    }
  }
    </script>
</body>
</html>

The ouput I’m wanting to get is a simple submenu so like this:

<ul> Title 
       <li> Order Number </li>
                <li>Product Name </li>
</ul>

The product name will be clickable and display an image

Where in the JSON is the title?

Also, are you looking for it to be like this?

Title
    Order Number
        Product Name

Where in this does the image go?

So I have wrote the title in the <ul> tag and placed it in HTML.

I have wrote some JS to place <li> tags within the <ul> tag. The name will be linking to the image thus making it display.

Essentially the layout will be as you have shown ^^ the product name will be clickable to display an image. Hope this makes sense

UPDATED THE CODE ABOVE TO THE NEWER VERSION