I need to render the below object into subsequent tr/tds via JSX...
{
"0": [
{
"colIndex": 0,
"data": {
"richTextModule": "Data row 1 cell 1"
}
},
{
"colIndex": 0,
"data": {
"richTextModule": "Data row 2 cell 1"
}
}
],
"1": [
{
"colIndex": 1,
"data": {
"richTextModule": "Data row 1 cell 2"
}
},
{
"colIndex": 1,
"data": {
"richTextModule": "Data row 2 cell 2"
}
}
],
"2": [
{
"colIndex": 2,
"data": {
"richTextModule": "Data row 1 cell 3"
}
},
{
"colIndex": 2,
"data": {
"richTextModule": "Data row 2 cell 3"
}
},
{
"colIndex": 2,
"data": {
"richTextModule": "Data row 3 cell 3"
}
}
]
}
I've tried
Object.values(obj).map((column, index) => {
return column.map((row, rowIndex) => {
return obj[index][rowIndex].data.richTextModule;
});
}
Expected output should be...
<tr>
<td>Data row 1 cell 1</td>
<td>Data row 1 cell 2</td>
<td>Data row 1 cell 3</td>
</tr>
<tr>
<td>Data row 2 cell 1</td>
<td>Data row 2 cell 2</td>
<td>Data row 2 cell 3</td>
</tr>
Any ideas on how to achieve this?
CodePudding user response:
Think what you're trying to do is:
<table>
{Object.values(obj).map((col, index) => <tr key={index}>{
col.map((row, rowIndex) => <td key={rowIndex}>${obj[index][rowIndex].data.richTextModule}</td>)
}</tr>
)}
</table>
or you could do:
<table>
{Object.values(obj).map((col, index) => {
return (
<tr key={index}>
{col.map((row, rowIndex) => {
return <td key={rowIndex}>${obj[index][rowIndex].data.richTextModule}</td>
})}
</tr>
)
})}
</table>
You should return in a map
, reference:
You also should add a key
, reference:
CodePudding user response:
Details are commented in example
const data={0:[{colIndex:0,data:{richTextModule:"Data row 1 cell 1"}},{colIndex:0,data:{richTextModule:"Data row 2 cell 1"}}],1:[{colIndex:1,data:{richTextModule:"Data row 1 cell 2"}},{colIndex:1,data:{richTextModule:"Data row 2 cell 2"}}],2:[{colIndex:2,data:{richTextModule:"Data row 1 cell 3"}},{colIndex:2,data:{richTextModule:"Data row 2 cell 3"}},{colIndex:2,data:{richTextModule:"Data row 3 cell 3"}}]};
// Flatten the object into an array of objects
let array = Object.values(data).flat();
console.log(array);
/*
Assign a new property to each object called "rowIndex"
Set the value as the first number in data.richTextModule
*/
array.forEach(obj => obj.rowIndex = parseInt(obj.data.richTextModule.match(/\d /)) -1);
console.log(array);
/*
Find the max value of rowIndex and colIndex values -- return the
two values as an array of pairs
*/
let RC = array.reduce((qty, cur) => {
if (qty[0] < cur.rowIndex) {
qty[0] = cur.rowIndex;
}
if (qty[1] < cur.colIndex) {
qty[1] = cur.colIndex;
}
return qty;
}, [0, 0]);
console.log(RC);
// Define an empty string
let htmlStr = '';
/*
- The outer loop creates a string of <tr>
- The inner loop will .find() the object in the array that matches the
current row and column indexes with it's rowIndex and colIndex
numbers.
- If there is such object, a string of <td> with data.richTextModule
as content is generated otherwise <td> </td> is generated.
- At the end of the inner loop the outer loop adds </td> to complete
the current row.
*/
for (let r=0; r < RC[0] 1; r ) {
htmlStr = `<tr>`;
for (let c=0; c < RC[1] 1; c ) {
let content = array.find(obj => (obj.rowIndex === r && obj.colIndex === c));
let cell = content ? `<td>${content.data.richTextModule}</td>` : `<td> </td>`;
htmlStr = cell;
}
htmlStr = `</tr>`;
}
console.log(htmlStr);
document.querySelector('table').innerHTML = htmlStr;
table, td {border: 1px solid black;}
<table></table>