Reputation: 345
I have a JavaScript Object which looks something like following:
{
"Finance": [
{
"id": 3,
"first_name": "Test",
"last_name": "Emp3",
"email": "[email protected]",
"department": "Finance",
"phone": "17894561235",
"job_title": "Manager",
"display_name": ""
}
],
"Account": [
{
"id": 4,
"first_name": "Test",
"last_name": "Emp4",
"email": "[email protected]",
"department": "Account",
"phone": "14567891236",
"job_title": "Manager",
"display_name": ""
}
],
"HR": [
{
"id": 5,
"first_name": "Test",
"last_name": "Emp5",
"email": "[email protected]",
"department": "HR",
"phone": "17894556556",
"job_title": "Manager",
"display_name": ""
}
]
} Getting the above data by following function call:
const [Data, setData] = useState();
const getdata = async () => {
setLoading(true);
let Data = [];
try {
let result = await getDATA(
subscription,
customer
);
let emp = result.data;
Data = emp;
console.log(result.data);
setData(Data);
} catch (e) {
setErrors(true);
setStatus(
<>
<FormattedMessage id="GENERAL.ERROR" />
<a
target="_blank"
rel="noopener noreferrer"
>
<FormattedMessage id="GENERAL.CONTACT_SUPPORT" />
</a>
</>
);
}
setLoading(false);
}
In the above JavaScript Object I have dynamic Department name which I have no idea what it can be.
My task is to make a Table something like this:
Following is my render:
<Modal.Body>
{data ? data.map((e, key) => {
return (
<Accordion defaultActiveKey="0">
<Card className="subscription-manager-expansion-card">
<Card.Header className="subscription-manager-expansion-header">
<Row>
<Col xs={12} sm={3} md={2} lg={1}>
<div className="rectangle-172">
<ContextAwareToggle eventKey="0"></ContextAwareToggle>
</div>
</Col>
<Col xs={6} sm={6} md={8} lg={8}>
<span classname="subscription-manager-expansion-header-title"> {e} </span>
</Col>
<Col xs={6} sm={3} md={2} lg={1}>
<Form.Check type="checkbox" onChange={checkAddSubscriber} />
</Col>
</Row>
</Card.Header>
<Accordion.Collapse eventKey="0">
<Card.Body>
<div className="widget4" key={e}>
<Table>
<thead>
<th className="FinancialModel-title-substring"></th>
<th className="FinancialModel-title-substring"></th>
</thead>
<tbody>
{e ? e.map((es, key) => {
return (
<tr key={es.first_name}>
<td className="subscription-manager-modal-table-name">{es.first_name + " " + es.last_name} </td>
<td className="subscription-manager-modal-table"> {es.email}</td>
<td>
<Form.Check type="checkbox" checked={isChecked} />
</td>
</tr>
);
}) : undefined}
</tbody>
</Table>
</div>
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
);
}) : undefined}
</Modal.Body>
Uncaught TypeError: Data.map is not a function
Please guide me through it.
Upvotes: 0
Views: 48
Reputation: 6702
You are getting the error Data.map is not a function
because on the first render, before you have set the data, Data
is undefined
.
Change the initialisation to to have a default value of an empty list:
const [data, setData] = useState([]);
As for your second question, you can use Object.entries()
, which gives you an array of [key, value]
pairs for your object. You can then map
over those, like so:
Object.entries(data)
.map(([departmentName, values]) =>{
return (<div>
<h1>departmentName</h1>
<DepartmentComponent info={values} />
</div>)
})
Upvotes: 1