Reputation: 820
I have data of nested objects in which I am getting data of my requirement, Now I want to loop through that object and render on UI, But I am not getting Idea how to do that as the UI is fully Dynamically dependent on data
.
My data
const countData = {
"current_month": {
"total_employes": 6,
"ariving": "+3",
"exiting": "-1",
"current_month": "April 2020",
"__typename": "CurrentMonthTotalEmp"
},
"previous_month": {
"total_employes": "3",
"arrived": "+2",
"exited": "-2",
"previous_month": "March 2020",
"__typename": "PrevMonthTotalEmp"
},
"__typename": "CurPrevMonthEmps"
}
to make it as array I doing this
const finalData =Object.entries(countData);
Now I want to loop this
please check my code-sandbox for full code
here in my code-sandbox I am rendering statically with HTML
Upvotes: 3
Views: 152
Reputation: 5123
First, you need to convert the countData
into a proper structure over which we can run our loop. to do that you need to change how you convert it to array to the following
const finalData = Object.values(countData)
After doing so we can now loop over the finalData
variable using a map
function like this.
{finalData.map(data => (
<div>{data.total_employes}</div>
<div>{data.ariving}</div>
))}
Moreover to handle missing key/values in the object you can do the following
{finalData.map(data => (
<div>{data.total_employes ? data.total_employes : 'NA'}</div>
<div>{data.ariving ? data.ariving : 'NA'}</div>
))}
Hope this helps
Upvotes: 1
Reputation: 202608
There is a lot of code duplication, we want to reduce that (DRY Principle). First, find the common code that abstractly describes your UI, i.e. a component that has a month/year label, some arrive/exit fields & labels, and an employee count. Convert what you want displayed to a component that takes these "standardized" props.
const MonthData = ({
arrive,
arriveLabel,
exit,
exitLabel,
totalEmployees,
month,
}) => (
<Fragment>
<label className="monthYr" align="left">
{month}
</label>
<div className="row countDiv">
<div className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6 total">
<label className="totalHeading">Total employees</label>
<div className="totalCount">{totalEmployees}</div>
</div>
<div className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
<button className="btn btn-outline-secondary button_Count form-control">
{arriveLabel}
<span className="badge badge-pill badge-primary ml-2">
{arrive}
</span>
</button>
<button className="btn btn-outline-secondary form-control">
{exitLabel}
<span className="badge badge-pill badge-primary ml-2">
{exit}
</span>
</button>
</div>
</div>
</Fragment>
);
I don't think I'd map these as you have different labeling for previous vs. current months, and you only ever display 2 months at a time. Just destructure from the countData
the two months' data.
const { current_month, previous_month } = countData;
return (
<div className="row container-fluid">
<div className="form-control graphHeading"> Manpower Graph</div>
<div className="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
<div className="row widthContainer">
<div className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
<MonthData
arrive={previous_month.arrived}
arriveLabel="arrived"
exit={previous_month.exited}
exitLabel="exited"
month={previous_month.previous_month}
totalEmployees={previous_month.total_employees}
/>
</div>
<div className="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
<MonthData
arrive={current_month.arriving}
arriveLabel="arriving"
exit={current_month.exiting}
exitLabel="exiting"
month={current_month.current_month}
totalEmployees={current_month.total_employees}
/>
</div>
</div>
</div>
</div>
);
Upvotes: 1
Reputation: 3718
you can use :
{
Object.keys(countData).map(key=>{
const month = countData[key]
return(
//you have access to month
<div>{month.total_employes}</div>
);
})
}
Upvotes: 1
Reputation: 2833
Most of your React applications will use data to render a UI. That's what React excels in.
You'll have to create a React component which receives the props for each month.
(total_employees
, ariving
, exiting
and current_month
) and renders them correctly.
for example:
const MonthComponent = ({ total_employees, ariving, exiting, current_month }) => {
//above return you can alter your data however you want using normal javascript
return (
//in 'return' you can return HTML or JSX to render your component.
<div>
<p>{total_employees}</p>
<p>{ariving}</p>
<p>{exiting}</p>
<p>{current_month}</p>
</div>
);
};
Now in your parent component you can loop over your array of data.
const ParentComponent = () => {
const countData = {
"current_month": {
"total_employes": 6,
"ariving": "+3",
"exiting": "-1",
"current_month": "April 2020",
"__typename": "CurrentMonthTotalEmp"
},
"previous_month": {
"total_employes": "3",
"arrived": "+2",
"exited": "-2",
"previous_month": "March 2020",
"__typename": "PrevMonthTotalEmp"
},
"__typename": "CurPrevMonthEmps"
}
const months = Object.keys(countData); // ["current_month", "previous_month"]
return (
months.map(month => (
// map over months and render your reusable component for each month
<MonthComponent {...countData[month]} />
))
);
};
Note: Spreading over ...countData[month]
is a shorthand property to pass every key-value pair of countData[month]
as a prop. I could also have written:
<MonthComponent
total_employees={countData[month].total_employees}
arrived={countData[month].arrived}
exited={countData[month].exited}
previous_month={countData[month].previous_month}
/>
Upvotes: 3
Reputation: 505
You can do something like this in your JSX code:
{finalData.map(value => (
<div>{value.something}</div>
))}
Upvotes: 1