Link to home
Start Free TrialLog in
Avatar of Babak Sekandari
Babak SekandariFlag for United States of America

asked on

Help displaying JSON in HTML

I'm experimenting to learn JavaScript.

Please help me understand why the code examples below worked or didn't work.

I start with a simple html page in one file and in a different file (menu.json) I have some JSON. I tried various codes within the script tag to retrieve the JSON and display it:


<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- meta tags removed for clarity -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
    <script>
      $(document).ready(function () {
          // tried various codes here
      });
    </script>
  </head>
  <body>
    <div>here</div>
  </body>
</html>

Open in new window


My goal is to get the JSON to appear within the <div> tags and replace the word, here.

This code worked as expected:

      $(document).ready(function () {
         $("div").load("menu.json");
      });

Open in new window

The word, "here" was replaced with the JSON,

{ "menu": { "id": "file", "value": "File", "popup": { "menuitem": [ { "value": "New", "onclick": "CreateNewDoc()" }, { "value": "Open", "onclick": "OpenDoc()" }, { "value": "Close", "onclick": "CloseDoc()" } ] } } }

Open in new window


This code also worked as expected:

      $(document).ready(function () {
        $.getJSON("menu.json", function (data) {
          console.log(data);
        });
      });

Open in new window

The menu JSON appeared in the console.

So, I expected that any of the below would also work:

$.getJSON("menu.json", function (data) {          
          $("div").text(data); // [object Object]
          $("div").text(JSON.parse(data)); // did nothing
          $("div").val(data); // did nothing
          $("div").append(data); // did nothing
});

Open in new window

None of those worked. The closest was,

 $("div").text(data); // [object Object]


This also worked for the console:

$.getJSON("menu.json", function (result) {
          $.each(result, function (i, field) {
            console.log(field);
          });
 });

Open in new window

But failed for the <div> tag:

$.getJSON("menu.json", function (result) {
  $.each(result, function (i, field) {
    $("div").append(field);
  });
});

Open in new window


I tried many other things, but to keep it less lengthy, I only showed a few.

Please help me understand how I can make this goal work and also explain why the code I tried failed.

Thanks in advance.

Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

Your object is not an array, so each does not work on the root of the object - as you can see the array starts at data.menu.popup.menuitem

I could not really guess what your menu would look like since you have strange value entries which only input fields and buttons have.

Here is an attempt that is not very menu-like. Please add some expected HTML for me to work on

https://jsfiddle.net/mplungjan/4pv1jewt/

$(document).ready(function() {
  const $menuDiv = $("#menu");
  const renderMenu = data => {
    console.log(data.menu.id)
    const $div = $('<div/>', {
      "id": data.menu.id,
      "data-value": data.menu.value
    }).text("Menu").appendTo($menuDiv);
    const $buttons = data.menu.popup.menuitem.forEach(obj => { 
      obj.type="button"; 
      const $button = $("<button/>",obj).text(obj.value);
      $div.append($button)
    })
  };
  // $.getJSON("menu.json", renderMenu)
  renderMenu(menu)
});

Open in new window

Avatar of Babak Sekandari

ASKER

I got that JSON at a site with examples. I just randomly picked it.

I'm not sure what your code is doing. That's the sort of code I want to eventually understand. But for now, it can't be that complicated to take the contents of a file and put it inside a div tag. The .load() function did it with one step. Outputting it to the console is also quick.

Suppose it was a simpler JSON like,

{"x": "y"}

I was able to get the letter y in the div tags with this:

 $.getJSON("simple.json", function (result) {

          $.each(result, function (i, field) {

            $("div").append(field);

But I wanted to get the whole thing in there.


I don't understand why none of these uncommented work:

  $.getJSON("simple.json", function (data) {

        // $("div").text(data); // [object Object]

        //  $("div").text(JSON.parse(data)); // did nothing

        //  $("div").text(JSON.stringify(data)); // did nothing

          // $("div").val(data); // did nothing

          // $("div").append(data); // did nothing

  });


The closest to working was 

$("div").text(data);

but that only gave me [object Object]

Maybe I can get the value out of that and put it in the div?




ASKER CERTIFIED SOLUTION
Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

The only one that worked was:

$("div").text(JSON.stringify(data)); 


Even this did not work:

      $(document).ready(function () {

        $.getJSON("menu.json", function (data) {

          console.log(JSON.parse(data));

        });



I tried with two JSON files.

simple.json:

{"x": "y"}


and

menu.json:

{

  "menu": {

    "id": "file",

    "value": "File",

    "popup": {

      "menuitem": [

        { "value": "New", "onclick": "CreateNewDoc()" },

        { "value": "Open", "onclick": "OpenDoc()" },

        { "value": "Close", "onclick": "CloseDoc()" }

      ]

    }

  }

}


I'm curious why the other two didn't work.

After this, I will learn how to parse out individual parts of the JSON.


$.getJSON("menu.json", function (data) {
delivers an object, so
JSON.parse(data) will not work.
JSON.stringify WILL work as you saw

When you have received an object from
  • fetch plus response.jons() or
  • from getJSON or
  • when you have JSON.parsed a JSON string
, it is no longer a JavaScript Object Notation string and you can then parse it(not JSON.parse, but JavaScript "decompose" or "iterate" which is ALSO called parse.

{"x":"y"} is a very simple object and has just a key and a value, so very easy to manipulate

THIS object is a nested object
{ // in your case data object
  "menu": { // an object 
    "id": "file", // a key:value pair
    "value": "File", // a key:value pair
    "popup": { // a key:object
       "menuitem": [ // a key: array (also an object) with 3 items
        { "value": "New", "onclick": "CreateNewDoc()" }, // an object with two key:value pairs
        { "value": "Open", "onclick": "OpenDoc()" },          // an object with two key:value pairs
        { "value": "Close", "onclick": "CloseDoc()" }         // an object with two key:value pairs
      ] // end of menuitem array
    } // end of popup object
  } // end of menu object
} // end of data object

Open in new window

Depending on what you need, you may need to parse/iterate the object using a recursive function

For example

https://jsfiddle.net/mplungjan/oLmw916u/

const keys = [], findKeys = (object, prevKey = '') => {
  Object.entries(object).forEach(([key,value]) => {
    const nestedKey = prevKey === '' ? key : `${prevKey}.${key}`;
    if (typeof object[key] !== 'object') return keys.push(`${nestedKey}:${value}`); // not an object
    findKeys(object[key], nestedKey); // recurse
  });
};
findKeys(result); // fill the keys array
console.log(keys.join("\n")); // display it

Open in new window


which produces

menu.id:file
menu.value:File
menu.popup.menuitem.0.value:New
menu.popup.menuitem.0.onclick:CreateNewDoc()
menu.popup.menuitem.1.value:Open
menu.popup.menuitem.1.onclick:OpenDoc()
menu.popup.menuitem.2.value:Close
menu.popup.menuitem.2.onclick:CloseDoc()

Open in new window