Search code examples
javascriptarraysjson

Inserting JSON data with 'insertAdjacentElement' instead of 'innerHTML'


I need to use JSON to fetch data dynamically into the page.

But I heard that innerHTML is not safe from XSS attacks - so I'd rather always use textContent instead of it.

For that I'd need to add the text containers with insertAdjacentElement instead of putting them in innerHTML = TEXT ` like so.

I tried to do that with the insertAdjacentElement - but the problem is it puts all JSON items in the same text container.

Is there a way to wrap every Object.key with <> and </> tags without innerHTML?

Thank you very much.

NOTE: Use (Ctrl + /) And (Alt + Left Mouse) to hide and show each method.

fetch("./b.json")
    .then(function (response) {
        return response.json();
    })
    .then(function (data) {
        console.log(data);

        const table = document.getElementById('data-input');
        
        const tableRow = document.createElement('tr');
        let th = document.createElement('th');
        let td = document.createElement('td');

        let textTitle = "";
        let text = "";

        for (let item of data) {
            // Required Method: insertAdjacentElement();

            table.insertAdjacentElement('afterbegin', tableRow);
            tableRow.insertAdjacentElement('beforeend', th);
            tableRow.insertAdjacentElement('beforeend', td);

            th.textContent += `${item.SpecifiedSeries}`;
            td.textContent += `
            ${item.Hero}
            ${item.Power}      
            `;

            // Original Method: innerHTML;

            // text += `
            //     <tr>
            //         <th>${item.SpecifiedSeries}</th>

            //         <td>${item.Hero}</td>
            //         <td>${item.Power}</td>
            //     </tr>
            // `;
        }

        // Original Method: innerHTML;

        // table.innerHTML = text;
    });
    
    // THE JSON FILE INCLUDED AS WELL:
    
    // [
    //     {
    //         "SpecifiedSeries": "Gravity Falls",
            
    //         "Hero": "Dipper & Mabel",
    //         "Power": "Cleverness, Determination..."
    //     },
        
    //     {
    //         "SpecifiedSeries": "Legend of Korra",
            
    //         "Hero": "Avatar Korra",
    //         "Power": "Mastering all 4 Elements..."
    //     }
    // ]
#container {
    position: fixed;
    z-index: 600;
    
    margin-top: 5%;

    overflow-y: scroll;

    left: 50%;
    transform: translate(-50%);

    bottom: 5%;

    height: clamp(48%, 90%, 90%);
    width: clamp(50%, 90%, 90%);

    border-radius: 24px;

    background-color: white;

    text-align: center;
}

#container table {
    margin-top: 5%;
}

table {
    font-family: sans-serif;
 
    width: 1400px;
    margin: 30px auto;
 
    box-shadow: 5px 10px 18px blue;
 
    table-layout: fixed;
 }
 
 table th {
    padding: 10px 0;
    background-color: #f4f4f4;
    border: thin solid #d4d4d4;
 }
 
 table td {
    padding: 10px;
    border: thin solid #d4d4d4;
    
    text-align: center;
    background-color: #fff;
 }
 
 table img {
    width: 70%;
 }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <link rel="stylesheet" href="a.css">
</head>
<body>
    <div id="container">
        <table>
          <thead>
            <tr>
              <th style="background-color: blue;"></th>
              <th>Hero</th>
              <th>Power</th>
            </tr>
          </thead>
          <tbody id="data-input"></tbody>
        </table>
      </div>

      <script src="a.js"></script>
</body>
</html>


Solution

  • You can modify the code to something along the lines of this.

    fetch("./b.json")
    .then(function (response) {
        return response.json();
    })
    .then(function (data) {
        const table = document.getElementById('data-input');
    
        data.forEach(function(item) {
            // Create table row
            const tableRow = document.createElement('tr');
    
            // Create table cells (td)
            const th = document.createElement('th');
            const tdHero = document.createElement('td');
            const tdPower = document.createElement('td');
    
            // Set text content for each cell
            th.textContent = item.SpecifiedSeries;
            tdHero.textContent = item.Hero;
            tdPower.textContent = item.Power;
    
            // Append cells to the row
            tableRow.appendChild(th);
            tableRow.appendChild(tdHero);
            tableRow.appendChild(tdPower);
    
            // Append row to the table body
            table.appendChild(tableRow);
        });
    })
    .catch(function(error) {
        console.log('Error fetching JSON: ', error);
    });