I have a 2D array within my Javascript. The array is assigned the variable ‘arr’ and looks like this:
[
[
"0",
{
cat_id: "1",
cat_name: "Tiger",
},
],
[
"1",
{
cat_id: "2",
cat_name: "Lion",
},
],
[
"2",
{
cat_id: "3",
cat_name: "Cheetah",
},
],
[
"3",
{
cat_id: "5",
cat_name: "Leopard",
},
],
]
I want to give the user a neat little HTML table on screen, with the keys being the header and the values being the rows, thus:
cat_id | cat_name |
---|---|
1 | Tiger |
2 | Lion |
3 | Cheetah |
4 | Leopard |
I’ve been looking at many articles on StackOverflow and the web in general, but I’m not a Javascript expert and, honestly, I can’t get anything to work. Any help greatly appreciated!
My HTML contains the empty table code:
const arr = [["0", { cat_id: "1", cat_name: "Tiger", },], ["1", { cat_id: "2", cat_name: "Lion", },], ["2", { cat_id: "3", cat_name: "Cheetah", },], ["3", { cat_id: "5", cat_name: "Leopard", },],]
var tableBody = document.getElementById("wrap");
tableBody.innerHTML = "";
arr.forEach(function (row) {
var newRow = document.createElement("tr");
tableBody.appendChild(newRow);
if (row instanceof Array) {
row.forEach(function (cell) {
var newCell = document.createElement("td");
newCell.textContent = cell;
newRow.appendChild(newCell);
});
} else {
newCell = document.createElement("td");
newCell.textContent = row;
newRow.appendChild(newCell);
}
});
<table id="wrap"></table>
Because arr is a 2D array, right now my code just produces this as a table:
0 [object Object]
1 [object Object]
2 [object Object]
3 [object Object]
I understand why this is happening, but my JS are simply not good enough to get the result I’m trying to achieve.
Edit
The properties of the nested objects won’t be known ahead of time so the solution needs to be dynamic.
eg:
arr = [
["0", { dog_id: "8866", dog_colour: "Brown", dog_desc: "Small, bit grumpy" }],
["1", { dog_id: "8867", dog_colour: "Black", dog_desc: "Nice dog" }],
["2", { dog_id: "8868", dog_colour: "Brown", dog_desc: "Dead" }],
["3", { dog_id: "8869", dog_colour: "Blonde", dog_desc: "Barks a lot" }],
];
2
Answers
Here is the working example:
Here is a slightly more robust solution, which will accommodate objects with different numbers of properties, and avoids the need to sort the keys by using a single array of column header keys to access each successive row’s properties.
It first gathers all the
Object.keys
of all the nested objects and uses these to build the header row. It then iterates over each object in the original array and uses the accumulated column keys to access the properties to build the value rows. If the property is not present in the object it uses nullish coallescing ?? to assign an empty string to the column for that row.see:
Original answer
Here is an example that iterates the
Object.entries
of each nested data object to first build a header row from the keys, and then data rows from the values. This assumes that any further columns will be added as properties to the single object at index1
of the nested arrays.It first maps the original array to be an 2d array of
[key, value]
tuples and sorts each array of tuples bykey
. It then iterates thekeys
of the first element in the array to create a header. It then proceeds to iterate each element in the array to build each data row.Relevant topics: