Reputation: 1534
Currently I am struggling with iterating over an object containing an array with objects. (and nested ones) I am trying to create a generic Table Component in React so it can be used by many views.
What did I setup?
tableData.map((prop, key) => {
return (
<TableRow key={key}>
<TableCell className={classes.tableCell} key={key}>
{prop.number}
</TableCell>
<TableCell className={classes.tableCell} key={key}>
{prop.TableType.max_occupancy}
</TableCell>
<TableCell className={classes.tableCell} key={key}>
{prop.price}
</TableCell>
<TableCell className={classes.tableCell} key={key}>
{prop.TableType.description}
</TableCell>
<TableCell className={classes.tableCell} key={key}>
<Button fullWidth color="primary">
Remove
</Button>
</TableCell>
</TableRow>
);
})
The problem that I am facing right now?
I can not create the content above in a dynamic way. I am encountering several issues like for example:
What would I like to achieve?
I would like to achieve something that is generic and can be used in a wide range of scenarios and does not clash with other pages where this component is being used.
In the end it should look something like this in a visual way:
What data do I have?
[
{
"id": 1,
"number": 1,
"status": true,
"price": 12,
"table_type_id": 1,
"venue_id": 1,
"TableType": {
"id": 1,
"description": "Small Table",
"max_occupancy": 3
}
},
{
"id": 2,
"number": 2,
"status": true,
"price": 2,
"table_type_id": 2,
"venue_id": 1,
"TableType": {
"id": 2,
"description": "Medium Table",
"max_occupancy": 6
}
}
]
The Codesandbox directory with the full project: https://codesandbox.io/embed/lwzz4j9mz?autoresize=1&eslint=1 The fill we are talking about is located at the Components/Table/Table.jsx. (I have added some dummy data in the comments that needs to be parsed to Table rows and cells)
Properties that needs be used in the view:
Hopefully someone can come up with a smart idea to help me out with this issue! Cheers for all the help and hopefully we can fix this together.
Upvotes: 0
Views: 108
Reputation: 1079
You should probably use an external library to get this done. But if you want to go for an in house approach this would be one way to go about it.
To the component, send the data and the header.The header should also specify how the data should be parsed to receive it's value.
var defaultTemaplate = '<TableRow><TableCell style={{ textAlign: "center" }}>Woooops! You haven\'t applied any tables for this venue yet. To start renting out tables you should add at least 3 tables tothe app. Just press the button above to start imediately.</TableCell></TableRow>'
var tableHead = [{
title: 'number',
type: 'data',
path: 'number'
},
{
title: 'TableType',
type: 'data',
path: 'TableType.description'
},
{
title: 'Edit/delete',
type: 'template',
templateString: '<button></button>'
}
] //for all columns
var tableData = [{
"id": 1,
"number": 1,
"status": true,
"price": 12,
"table_type_id": 1,
"venue_id": 1,
"TableType": {
"id": 1,
"description": "Small Table",
"max_occupancy": 3
}
},
{
"id": 2,
"number": 2,
"status": true,
"price": 2,
"table_type_id": 2,
"venue_id": 1,
"TableType": {
"id": 2,
"description": "Medium Table",
"max_occupancy": 6
}
}
]
console.log(genRows(tableData))
function getTableCells(data) {
return tableHead.map((opts) => {
if (opts.type === 'data') {
return `<TableCell className={classes.tableCell}>${_.at(data, opts.path)}</TableCell>`
}
if (opts.type === 'template') {
return opts.templateString
}
})
}
function genRows(tableData) {
if (tableData.length < 0) return defaultTemaplate;
return tableData.map((rowData) => `<TableRow>${getTableCells(rowData)}</TableRow>`)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
This is just an example to demonstrate one approach you could take, not full fledged code and can defenetly be improved.
Upvotes: 1