'Fetching Data from JSON and creating an HTML Table through Javascript - Not Working
I'm trying to create a table populated by an external .JSON file through using JavaScript. It is not working. When the .JSON data was placed in the .JS code it worked, but once I used "fetch" to retrieve data externally it stopped working and does not display the details.
HTML
<input type="button" onclick="CreateTableFromJSON()" value="Create Table From JSON" />
<p id="showData"></p>
JavaScript
fetch('about-us.json')
.then((response) => response.json())
.then((data) => {
data.forEach(CreateTableFromJSON);
})
.catch((error) => {
console.error('Error:', error);
});
function CreateTableFromJSON() {
// EXTRACT VALUE FOR HTML HEADER.
// ('Book ID', 'Book Name', 'Category' and 'Price')
var col = [];
for (var i = 0; i < myBooks.length; i++) {
for (var key in myBooks[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
// CREATE DYNAMIC TABLE.
var table = document.createElement("table");
// CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.
var tr = table.insertRow(-1); // TABLE ROW.
for (var i = 0; i < col.length; i++) {
var th = document.createElement("th"); // TABLE HEADER.
th.innerHTML = col[i];
tr.appendChild(th);
}
// ADD JSON DATA TO THE TABLE AS ROWS.
for (var i = 0; i < myBooks.length; i++) {
tr = table.insertRow(-1);
for (var j = 0; j < col.length; j++) {
var tabCell = tr.insertCell(-1);
tabCell.innerHTML = myBooks[i][col[j]];
}
}
// FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
var divContainer = document.getElementById("showData");
divContainer.innerHTML = "";
divContainer.appendChild(table);
}
External .JSON File (about-us.json)
[
{
"Book ID": "1",
"Book Name": "Computer Architecture",
"Category": "Computers",
"Price": "125.60"},
{
"Book ID": "2",
"Book Name": "Asp.Net 4 Blue Book",
"Category": "Programming",
"Price": "56.00"
},
{
"Book ID": "3",
"Book Name": "Popular Science",
"Category": "Science",
"Price": "210.40"
}]
Solution 1:[1]
I had a little time on my hands so I rewrote your code which breaks down the separate steps to make headings, rows, and cells using map
and join
, and then uses a template string to piece it together. Basically you're just building up small parts of the final HTML as various strings that you combine.
const json='[{"Book ID":"1","Book Name":"Computer Architecture","Category":"Computers","Price":"125.60"},{"Book ID":"2","Book Name":"Asp.Net 4 Blue Book","Category":"Programming","Price":"56.00"},{"Book ID":"3","Book Name":"Popular Science","Category":"Science","Price":"210.40"}]';
// Cache the button, and add an event listener to
// it which calls the API (returns data after two seconds)
const button = document.querySelector('button');
button.addEventListener('click', fetchData, false);
// Mock API
function mockApi() {
return new Promise(res => {
setTimeout(() => res(json), 2000);
});
}
// Calls the API, parses the json, then
// calls createTable with the data
function fetchData() {
button.textContent = 'Loading...';
button.disabled = true;
mockApi()
.then(res => JSON.parse(res))
.then(createTable);
}
// `map` over the keys of first object
// in the array, and return a string of HTML
function getColumnHeadings(data) {
return Object.keys(data[0]).map(key => {
return `<td>${key}</td>`;
}).join('');
}
// `map` over each object in the array,
// and return a string of HTML. It calls
// `getCells` on each object
function getRows(data) {
return data.map(obj => {
return `<tr>${getCells(obj)}</tr>`
}).join('');
}
// `map` over the values of an object
// and return a string of HTML
function getCells(obj) {
return Object.values(obj).map(value => {
return `<td>${value}</td>`;
}).join('');
}
function createTable(data) {
// Get the headings, and the rows
const headings = getColumnHeadings(data);
const rows = getRows(data);
// Create an HTML string
const html = `
<table>
<tbody>
<tr class="headings">${headings}</tr>
${rows}
</tbody>
</table>
`
// Add the string to the DOM
document.body.insertAdjacentHTML('beforeend', html);
}
table { border-collapse: collapse; border: 1px solid #565656; margin-top: 1em; width: 100%; }
td { padding: 0.6em 0.3em; border: 1px solid #dfdfdf; }
.headings { font-weight: 700; background-color: #dfdfdf; }
button:hover { cursor: pointer; }
<button>Build table</button>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Andy |