I would like to insert parsed JSON data into a HTML table via Javascript. I think I am close to a solution, but can't figure out the final step.
Goal: I need to insert the name, age, secretIdentity and powers of three superheroes into their respective columns in a table. The data comes from a JSON file. I parsed it and it is ready to use in Javascript. I want to loop through the objects within the data and insert the correct data in the cells. I am not allowed to use jQuery or similar techniques.
Problem: The problem is that I can not seem to loop through the objects (name, age etc) for each superhero and add it to the cell. How do I target/reference the objects for use in a loop? For example, this 'works', but gives the wrong result since I don't want to loop through the names:
JavaScript code:
for(i = 0; i < members.length; i ) {
function addRow(tableID) {
let tableRef = document.getElementById(tableID);
let newRow = tableRef.insertRow(-1);
for(x = 0; x < 4; x ) {
let newCell = newRow.insertCell(0);
let newText = document.createTextNode(members[i].name);
newCell.appendChild(newText);
}
Instead, I want to loop through the object like this, in a horizontal way.
Expected solution: I expect the solution to look something like this, but it doesn't work:
for(x = 0; x < 4; x ) {
let newCell = newRow.insertCell(0);
let newText = document.createTextNode(members[i].obj[x]);
newCell.appendChild(newText);
JSON data:
const data =
[ { squadName : 'Super Hero Squad'
, homeTown : 'Metro City'
, formed : 2016
, secretBase : 'Super tower'
, active : true
, members :
[ { name : 'Molecule Man'
, age : 29
, secretIdentity : 'Dan Jukes'
, powers :
[ 'Radiation resistance'
, 'Turning tiny'
, 'Radiation blast'
] }
, { name : 'Madame Uppercut'
, age : 39
, secretIdentity : 'Jane Wilson'
, powers :
[ 'Million tonne punch'
, 'Damage resistance'
, 'Superhuman reflexes'
] } ] }
//, {}
]
Is there anyone that is able to help out? Thanks in advance!
CodePudding user response:
Just loop through each property of object member[i]
for (i = 0; i < members.length; i ) {
addRow('table', members[i]);
}
function addRow(tableID, member) {
let tableRef = document.getElementById(tableID);
let newRow = tableRef.insertRow(-1);
for (let prop in member) {
let newCell = newRow.insertCell(-1);
let newText = document.createTextNode(member[prop]);
newCell.appendChild(newText);
}
}
CodePudding user response:
I'm not 100% sure about what columns you need but, I think this is close what you wanted. Hopefully you can see the general pattern to creating a DOM element, filling it with data and appending it to the table.
const data =
[ { squadName : 'Super Hero Squad'
, homeTown : 'Metro City'
, formed : 2016
, secretBase : 'Super tower'
, active : true
, members :
[ { name : 'Molecule Man'
, age : 29
, secretIdentity : 'Dan Jukes'
, powers :
[ 'Radiation resistance'
, 'Turning tiny'
, 'Radiation blast'
] }
, { name : 'Madame Uppercut'
, age : 39
, secretIdentity : 'Jane Wilson'
, powers :
[ 'Million tonne punch'
, 'Damage resistance'
, 'Superhuman reflexes'
] } ] }
//, {}
]
const table = document.getElementById('root');
data.forEach(squad => {
squad.members.forEach(hero => {
const tr = document.createElement("tr")
const nameTd = document.createElement("td")
nameTd.append(hero.name)
const ageTd = document.createElement("td")
ageTd.append(hero.age)
const secretTd = document.createElement("td")
secretTd.append(hero.secretIdentity)
const powersTd = document.createElement("td")
powersTd.append(hero.powers.join(', '))
tr.append(nameTd)
tr.append(ageTd)
tr.append(secretTd)
tr.append(powersTd)
table.append(tr)
})
})
td {
border: solid black 1px;
}
<table id="root">
</table>
CodePudding user response:
What you are looking for in the nested loop, the horizontal one, is "for in". "for in" will loop through the properties of an Object. Refer to this article
https://www.w3schools.com/js/js_loop_forin.asp
But, I do not recommend you to use this method - simply access key value to generate each collumn (<td>), because the order of keys is not guaranteed in a loop. You still have to check the key in the nested loop to make it safe.
Does JavaScript guarantee object property order?
CodePudding user response:
you can do that:
const data =
[ { squadName : 'Super Hero Squad'
, homeTown : 'Metro City'
, formed : 2016
, secretBase : 'Super tower'
, active : true
, members :
[ { name : 'Molecule Man'
, age : 29
, secretIdentity : 'Dan Jukes'
, powers :
[ 'Radiation resistance'
, 'Turning tiny'
, 'Radiation blast'
] }
, { name : 'Madame Uppercut'
, age : 39
, secretIdentity : 'Jane Wilson'
, powers :
[ 'Million tonne punch'
, 'Damage resistance'
, 'Superhuman reflexes'
] }
, { name : 'Eternal Flame'
, age : 1000000
, secretIdentity : 'Unknow'
, powers :
[ 'night lighting'
] } ] }
//, {}
]
const keys_0 = [ 'squadName', 'homeTown', 'formed', 'secretBase', 'active' ]
const keys_1 = [ 'name', 'age', 'secretIdentity', 'powers' ]
data.forEach(herosGroup=>
{
let
tabEl = document.createElement('table')
, tHead = tabEl.createTHead()
, tBody = tabEl.createTBody()
, newRow = tHead.insertRow()
;
tabEl.className = 'top'
document.body.appendChild(tabEl)
keys_0.forEach(prop=> newRow.insertCell().textContent = prop )
newRow = tBody.insertRow()
keys_0.forEach(prop=> newRow.insertCell().textContent = herosGroup[prop] )
// 'name', 'age', 'secretIdentity', 'powers' trip...
tabEl = document.createElement('table')
tHead = tabEl.createTHead()
tBody = tabEl.createTBody()
newRow = tHead.insertRow()
document.body.appendChild(tabEl)
keys_1.forEach(prop=> newRow.insertCell().textContent = prop )
herosGroup.members.forEach(hero=>
{
newRow = tBody.insertRow()
keys_1.forEach(prop=>
{
if (prop!='powers') newRow.insertCell().textContent = hero[prop]
else newRow.insertCell().innerHTML = hero[prop].join('<br>')
})
})
}) // forEach(herosGroup=>
body {
font-family : Arial, Helvetica, sans-serif;
font-size : 14px;
}
table {
border-collapse : collapse;
margin : .7em 1em;
}
table.top {
margin-top : 1em;
}
td {
padding : .2em .8em;
border : 1px solid darkblue;
vertical-align : text-top;
white-space : nowrap;
}
thead {
background-color: aquamarine;
font-weight : bold;
}