1

This is my code and I am trying to pull in JSON data from an API.

The data is being successfully pulled but it is not coming in table format. It is coming as a continuous horizontal string.

if (this.readyState == 4 && this.status == 200) {
   // Typical action to be performed when the document is ready:
var respoTxt = xhttp.responseText;
var myObj = JSON.parse(respoTxt); 
document.getElementById("demo").innerHTML = '<table><tr><thead>' + 
myObj["dataset"]["column_names"][5] + '</thead><thead>' + myObj["dataset"]
["column_names"][6] + '</thead></tr>';
myObj["dataset"]["data"].forEach(function(p, i) {
//Below is 1st code version:
// var tr = document.createElement("tr");
// document.getElementById("demo").appendChild(tr);
// var td1 = document.createElement("td");
// tr.appendChild(td1);
// var td2 = document.createElement("td");
// tr.appendChild(td2);
// td1.innerHTML = myObj["dataset"]["data"][i][5];
// td2.innerHTML = myObj["dataset"]["data"][i][6];

document.getElementById("demo").innerHTML += '<tr>';
document.getElementById("demo").innerHTML += '<td>' + myObj["dataset"]
["data"][i][5] + '</td>';
document.getElementById("demo").innerHTML += '<td>' + myObj["dataset"]
["data"][i][6] + '</td>';
document.getElementById("demo").innerHTML += '</tr>';

//Here's the 3rd code version:
// document.getElementById("demo").innerHTML += '<tr><td>' + 
myObj["dataset"]["data"][i][5] + '</td><td>' + myObj["dataset"]["data"][i]
[6] + '</td></tr>';
});
document.getElementById("demo").innerHTML += '</table>';
}

I have used 3 different types of code inside (2 of them marked in comments above and below the active one).

None of them are showing the data in table format.

Here's the Codepen.

5
  • 2
    Instead of appending everything to innerHTML, add them to a temporary string, then assign that to innerHTML at the end. Commented May 14, 2017 at 17:21
  • @Barmar You mean inside the loop? Like assigning a var p = '<tr>'; var q = '<td>' + myObj["dataset"]["data"][i][5] + '</td>'; var r = '</tr>'; and then .innerHTML = p + q + r? Commented May 14, 2017 at 17:31
  • 1
    I mean var html = '<table><tr><thead>' before the loop, then html += '<td> + ... </td>'; inside the loop, then finally .innerHTML = html; at the end. Commented May 14, 2017 at 17:33
  • @Barmar Thanks so much, it worked! If possible, I would really like to know why it worked in this way rather than directly adding to the .innerHTML. What's going on inside? Commented May 14, 2017 at 17:41
  • Explained in my answer Commented May 14, 2017 at 17:48

2 Answers 2

1

The problem is that when you set the innerHTML of an element, the browser automatically closes any unopened tags, because it has to parse whatever you've assigned as complete HTML. So you can't concatenate the opening tag, contents, and closing tags in separate assignments.

The solution is to assign all the HTML to a string variable as you're building it up, then assign that to .innerHTML at the very end. This is also more efficient, since it doesn't have to keep parsing HTML.

if (this.readyState == 4 && this.status == 200) {
  // Typical action to be performed when the document is ready:
  var respoTxt = xhttp.responseText;
  var myObj = JSON.parse(respoTxt);
  var html = '<table><tr><thead>' +
    myObj["dataset"]["column_names"][5] + '</thead><thead>' + myObj["dataset"]
    ["column_names"][6] + '</thead></tr>';
  myObj["dataset"]["data"].forEach(function(p, i) {
    html += '<tr>';
    html += '<td>' + myObj["dataset"]
      ["data"][i][5] + '</td>';
    html += '<td>' + myObj["dataset"]
      ["data"][i][6] + '</td>';
    html += '</tr>';

  });
  html += '</table>';
  document.getElementById('demo').innerHTML = html;
}

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! Thank you, Barmar. I researched a lot on this question on the forum, however most answers were in jQuery format. Hopefully, this will be helpful for the JS enthusiasts like me.
1

Little bit modification to your code.

Please use it in the below manner

document.getElementById("demo").innerHTML = '<table><thead><tr><th>' + 
myObj["dataset"]["column_names"][5] + '</th><th>' + myObj["dataset"]
["column_names"][6] + '</th></tr></thead>';   

3 Comments

Didn't get you. Where should I use it?
Okay, but the row data are still in the string format.
You should use a single variable to create the table and then append that variable to demo using innerHTML

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.