将嵌套的JSON数据转换为表

时间:2022-10-24 17:23:20

I'm trying to convert the nested JSON data into a HTML table, but it kept throwing error.

我正在尝试将嵌套的JSON数据转换为HTML表,但它一直在抛出错误。

I am not sure where I did wrong. Maybe something's wrong with the method of accessing the array inside the object?

我不确定我错在哪里。也许在对象内部访问数组的方法有问题?

It kept throwing this error:

它一直抛出这个错误:

"Cannot set property 'innerHTML' of null"

“无法设置属性'innerHTML'为null”

Below is the code I wrote :

以下是我写的代码:

function DonutTable(array){
    //create a table element
    var table = document.createElement("table");
    //create header columns

    var col = Object.keys(array[0]); //array of keys
    //write keys onto the header cell
    var tr = table.insertRow(-1);
    col.forEach(function(key){
        var th = document.createElement("th");
        th.textContent = key;
        tr.appendChild(th);
    });

    //create rows to hold the rest of the data
    array.forEach(function(obj){
        //for each obj in the main array, create a row
        var data_row = table.insertRow(-1);
        //for each header in the col array, populate data
        col.forEach(function(key){
            var tabCell = data_row.insertCell(-1);
            if (key==="batters"){
                //grab the value of batters and access value of batter
                obj["batters"]["batter"].forEach(function(e){
                    //for each e in batter, create a div element
                    var div = document.createElement("div");
                    //write on the div 
                    div.textContent =  e.type + "(" + e.id + ")";
                    tabCell.appendChild(div); })
                }
            if (Array.isArray(obj[key])){ //check if a value of a key is an array
                obj[key].forEach(function(topping){
                    //for each obj in topping, get id and type 
                    var div = document.createElement("div");
                    div.textContent =  topping.type + "(" + topping.id + ")";
                    tabCell.appendChild(div);
                })
            }
            else{
                tabCell.textContent = obj[key];
            }


                })
            })


    var divContainer = document.getElementById("showTable");
    divContainer.innerHTML = "";
    divContainer.appendChild(table);

}

var donut = [
    {
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55,
        "batters":
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" },
                        { "id": "1002", "type": "Chocolate" },
                        { "id": "1003", "type": "Blueberry" },
                        { "id": "1004", "type": "Devil's Food" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5005", "type": "Sugar" },
                { "id": "5007", "type": "Powdered Sugar" },
                { "id": "5006", "type": "Chocolate with Sprinkles" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    },
    {
        "id": "0002",
        "type": "donut",
        "name": "Raised",
        "ppu": 0.55,
        "batters": 
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5005", "type": "Sugar" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    },
    {
        "id": "0003",
        "type": "donut",
        "name": "Old Fashioned",
        "ppu": 0.55,
        "batters":
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" },
                        { "id": "1002", "type": "Chocolate" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    }
]
DonutTable(donut);

<html>
    <head>
        <title>HTML Donut Table from JSON</title>
        <script type="text/javascript" src="script.js"></script>
    </head>
    <body>
        <input type="button" value="Generate a table" onclick="DonutTable()">
        <div id="showTable"></div>
    </body>
</html>

2 个解决方案

#1


2  

In Chrome, set a breakpoint right after you declare your divContainer. Based on the code, it looks like divContainer is null because you are running the JavaScript before the HTML in on the page. Either move the JS into a document.ready type function or move the script section to below the HTML.

在Chrome中,在声明divContainer后立即设置断点。基于代码,看起来divContainer为null,因为您在页面上的HTML之前运行JavaScript。将JS移动到document.ready类型函数或将脚本部分移动到HTML下面。

#2


2  

This is your exact code that I just split into JS and HTML parts.

这是我刚才分成JS和HTML部分的确切代码。

It works on initial run since donut array is explicitly passed to DonutTable() function. It does not work on button click since your HTML calls DonutTable()with no parameters.

它适用于初始运行,因为环形数组显式传递给DonutTable()函数。它不适用于按钮单击,因为您的HTML调用没有参数的DonutTable()。

function DonutTable(array){
    //create a table element
    var table = document.createElement("table");
    //create header columns

    var col = Object.keys(array[0]); //array of keys
    //write keys onto the header cell
    var tr = table.insertRow(-1);
    col.forEach(function(key){
        var th = document.createElement("th");
        th.textContent = key;
        tr.appendChild(th);
    });

    //create rows to hold the rest of the data
    array.forEach(function(obj){
        //for each obj in the main array, create a row
        var data_row = table.insertRow(-1);
        //for each header in the col array, populate data
        col.forEach(function(key){
            var tabCell = data_row.insertCell(-1);
            if (key==="batters"){
                //grab the value of batters and access value of batter
                obj["batters"]["batter"].forEach(function(e){
                    //for each e in batter, create a div element
                    var div = document.createElement("div");
                    //write on the div 
                    div.textContent =  e["type"] + "(" + e["id"] + ")";
                    tabCell.appendChild(div); })
                }
            else if (Array.isArray(obj[key])){ //check if a value of a key is an array
                obj[key].forEach(function(topping){
                    //for each obj in topping, get id and type 
                    var div = document.createElement("div");
                    div.textContent =  topping.type + "(" + topping.id + ")";
                    tabCell.appendChild(div);
                })
            }
            else{
                tabCell.textContent = obj[key];
            }


                })
            })


    var divContainer = document.getElementById("showTable");
    divContainer.innerHTML = "";
    divContainer.appendChild(table);

}

var donut = [
    {
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55,
        "batters":
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" },
                        { "id": "1002", "type": "Chocolate" },
                        { "id": "1003", "type": "Blueberry" },
                        { "id": "1004", "type": "Devil's Food" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5005", "type": "Sugar" },
                { "id": "5007", "type": "Powdered Sugar" },
                { "id": "5006", "type": "Chocolate with Sprinkles" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    },
    {
        "id": "0002",
        "type": "donut",
        "name": "Raised",
        "ppu": 0.55,
        "batters": 
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5005", "type": "Sugar" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    },
    {
        "id": "0003",
        "type": "donut",
        "name": "Old Fashioned",
        "ppu": 0.55,
        "batters":
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" },
                        { "id": "1002", "type": "Chocolate" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    }
]
DonutTable(donut);
<html>
    <head>
        <title>HTML Donut Table from JSON</title>
        <script type="text/javascript" src="script.js"></script>
    </head>
    <body>
        <input type="button" value="Generate a table" onclick="DonutTable()">
        <div id="showTable"></div>
    </body>
</html>

#1


2  

In Chrome, set a breakpoint right after you declare your divContainer. Based on the code, it looks like divContainer is null because you are running the JavaScript before the HTML in on the page. Either move the JS into a document.ready type function or move the script section to below the HTML.

在Chrome中,在声明divContainer后立即设置断点。基于代码,看起来divContainer为null,因为您在页面上的HTML之前运行JavaScript。将JS移动到document.ready类型函数或将脚本部分移动到HTML下面。

#2


2  

This is your exact code that I just split into JS and HTML parts.

这是我刚才分成JS和HTML部分的确切代码。

It works on initial run since donut array is explicitly passed to DonutTable() function. It does not work on button click since your HTML calls DonutTable()with no parameters.

它适用于初始运行,因为环形数组显式传递给DonutTable()函数。它不适用于按钮单击,因为您的HTML调用没有参数的DonutTable()。

function DonutTable(array){
    //create a table element
    var table = document.createElement("table");
    //create header columns

    var col = Object.keys(array[0]); //array of keys
    //write keys onto the header cell
    var tr = table.insertRow(-1);
    col.forEach(function(key){
        var th = document.createElement("th");
        th.textContent = key;
        tr.appendChild(th);
    });

    //create rows to hold the rest of the data
    array.forEach(function(obj){
        //for each obj in the main array, create a row
        var data_row = table.insertRow(-1);
        //for each header in the col array, populate data
        col.forEach(function(key){
            var tabCell = data_row.insertCell(-1);
            if (key==="batters"){
                //grab the value of batters and access value of batter
                obj["batters"]["batter"].forEach(function(e){
                    //for each e in batter, create a div element
                    var div = document.createElement("div");
                    //write on the div 
                    div.textContent =  e["type"] + "(" + e["id"] + ")";
                    tabCell.appendChild(div); })
                }
            else if (Array.isArray(obj[key])){ //check if a value of a key is an array
                obj[key].forEach(function(topping){
                    //for each obj in topping, get id and type 
                    var div = document.createElement("div");
                    div.textContent =  topping.type + "(" + topping.id + ")";
                    tabCell.appendChild(div);
                })
            }
            else{
                tabCell.textContent = obj[key];
            }


                })
            })


    var divContainer = document.getElementById("showTable");
    divContainer.innerHTML = "";
    divContainer.appendChild(table);

}

var donut = [
    {
        "id": "0001",
        "type": "donut",
        "name": "Cake",
        "ppu": 0.55,
        "batters":
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" },
                        { "id": "1002", "type": "Chocolate" },
                        { "id": "1003", "type": "Blueberry" },
                        { "id": "1004", "type": "Devil's Food" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5005", "type": "Sugar" },
                { "id": "5007", "type": "Powdered Sugar" },
                { "id": "5006", "type": "Chocolate with Sprinkles" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    },
    {
        "id": "0002",
        "type": "donut",
        "name": "Raised",
        "ppu": 0.55,
        "batters": 
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5005", "type": "Sugar" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    },
    {
        "id": "0003",
        "type": "donut",
        "name": "Old Fashioned",
        "ppu": 0.55,
        "batters":
            {
                "batter":
                    [
                        { "id": "1001", "type": "Regular" },
                        { "id": "1002", "type": "Chocolate" }
                    ]
            },
        "topping":
            [
                { "id": "5001", "type": "None" },
                { "id": "5002", "type": "Glazed" },
                { "id": "5003", "type": "Chocolate" },
                { "id": "5004", "type": "Maple" }
            ]
    }
]
DonutTable(donut);
<html>
    <head>
        <title>HTML Donut Table from JSON</title>
        <script type="text/javascript" src="script.js"></script>
    </head>
    <body>
        <input type="button" value="Generate a table" onclick="DonutTable()">
        <div id="showTable"></div>
    </body>
</html>