Search code examples
javascriptfor-loophtml-tableappendchild

Loop through JSON data and appendChild <TR> is putting data in one row?


Background: I thought that I was going to end up with a dynamically created table that had the same number of <TR> tags as entries in the JSON data.

Result: The loop is only creating one table TR and putting all the data in one row.

Below is a snippet of the loop and table creation.

var tbl = document.createElement("table");
  var tblBody = document.createElement("tbody");
  var row = document.createElement("tr");
    var tdname = document.createElement('td');
    var tddate = document.createElement('td');
    var tdassigned = document.createElement('td');


    for (var i in data) {

    console.log("Hello world!" + i);
    tdname.appendChild(document.createTextNode(data[i].name));
    tddate.appendChild(document.createTextNode(data[i].date));
    tdassigned.appendChild(document.createTextNode(data[i].assigned));
    row.appendChild(tdname);
    row.appendChild(tddate);
    row.appendChild(tdassigned);


    }
    tblBody.appendChild(row);

    tbl.appendChild(tblBody);
    document.getElementById("tasklist").appendChild(tbl);

Question: Do I need to create a unique row variable for each loop?


Solution

  • There were a couple of issues:

    1. You're appending the text to the td, without clearing them. You can instead do document.createElement('td') within the loop for each of your data points.
    2. You need a row for each iteration of data, this can also be done within the loop.
    3. Please use let and const in place of var. Please see this post for more information.

    Try something like this:

    const data = [{
        name: 'name1',
        date: 'date1',
        assigned: 'assigned1'
      },
      {
        name: 'name2',
        date: 'date2',
        assigned: 'assigned2'
      },
      {
        name: 'name3',
        date: 'date3',
        assigned: 'assigned3'
      },
    ];
    
    let tbl = document.createElement("table");
    let tblBody = document.createElement("tbody");
    data.forEach(d => {
      let row = document.createElement("tr");
      row.appendChild(document.createTextNode(d.name));
      row.appendChild(document.createTextNode(d.date));
      row.appendChild(document.createTextNode(d.assigned));
      tblBody.appendChild(row);
    });
    
    tbl.appendChild(tblBody);
    document.getElementById("tasklist").appendChild(tbl);
    <div id='tasklist'></div>

    Hope this helps,