Reputation: 59
I have data from an API and I want to map through the values of it. But not able to do so. I get the "Cannot read property 'map' of undefined" error. I am not able to figure out why I get this error
I have tried all possible solutions. The code works fine if there is no map function in it.
class MyVerticallyCenteredModal extends React.Component {
render() {
return (
<Modal
{...this.props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
dialogClassName="farmer-modal"
centered
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
DETAILS
</Modal.Title>
</Modal.Header>
<Modal.Body>
<h5>Farm No: <span className="header-values"> {this.props.values.Farm_No}</span> </h5>
<h5>Farmer No: <span className="header-values"> {this.props.values.Farmer_Reg_Number}</span> </h5>
<h5>Farmer Name: <span className="header-values"> {this.props.values.Farmer_Name} </span> </h5>
<h5>Village: <span className="header-values"> {this.props.values.Farmer_Village} </span> </h5>
<h5>Farm Area: <span className="header-values"> {this.props.values.Farm_Area} </span> </h5>
<br/>
<table className="farmer-table">
<tr className="farmer-table-row">
<th className="farmer-table-header">Season</th>
<th className="farmer-table-header">Crop Name</th>
<th className="farmer-table-header">Crop Area</th>
<th className="farmer-table-header">Crop Type</th>
<th className="farmer-table-header">Estimated Quantity</th>
<th className="farmer-table-header">Organic Status</th>
<th className="farmer-table-header">Crop Total</th>
</tr>
{
this.props.values.Crop_Details.map((item, key) => (
<div>
<tr className="farmer-table-row">
<td className="farmer-table-data">{item.season}</td>
</tr>
</div>
))}
</table>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.props.onHide}>Close</Button>
</Modal.Footer>
</Modal>
);
}
}
this is the response from the API
Crop_Details: Array(3)
0: {Season: "Perennial", Organic_Status: "Organic", Crop_Name: "BananaFresh", Crop_Type: "Inter", Crop_Area: "0.000000", …}
1: {Season: "Perennial", Organic_Status: "Organic", Crop_Name: "Blackpepper(ungarbled)", Crop_Type: "Inter", Crop_Area: "0.000000", …}
2: {Season: "Perennial", Organic_Status: "Organic", Crop_Name: "CoffeeArabica-Cherry", Crop_Type: "Main", Crop_Area: "0.200000", …}
length: 3
Farm_Area: "0.200078750"
Farm_No: "KA28tdfg401"
Farmer_Name: "Lakshmamma"
Farmer_Reg_Number: "KA2301075ub74"
Farmer_Village: "Dbhyt"
Now I got the error resolved. But the values for Crop_Details alone are not getting displayed
But there are three entries in crop details and so three table rows are created. I even checked the props and all values are present in it.
Upvotes: 1
Views: 141
Reputation: 16152
First of all you need to validate your data, you are getting that error because the variable is undefined. Change your code to the following. You are using <td className="farmer-table-data">{item.season}</td>
from the output in your question season starts with an uppercase S
class MyVerticallyCenteredModal extends React.Component {
state = {
cropDetails: [],
Farm_No: '',
Farmer_Reg_Number: '',
Farmer_Name: '',
Farmer_Village: '',
Farm_Area: '',
show: false
}
componentDidMount = () => {
// fetch data or get data from props
const data = this.props.values;
// validate your data
this.setState({
cropDetails: data && data.Crop_Details || [],
Farm_No: data && data.Farm_No || '',
Farmer_Reg_Number: data && data.Farmer_Reg_Number || '',
Farmer_Name: data && data.Farmer_Name || '',
Farmer_Village: data && data.Farmer_Village || '',
Farm_Area: data && data.Farm_Area || '',
})
}
render() {
const items = this.state.cropDetails.map((item, key) => (
<tr>
<td>{item.Season}</td>
<td>{item.Crop_Name}</td>
<td>{item.Crop_Area}</td>
<td>{item.Crop_Type}</td>
</tr>
));
return (
<Modal
{...this.props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
dialogClassName="farmer-modal"
centered
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
DETAILS
</Modal.Title>
</Modal.Header>
<Modal.Body>
<h5>Farm No: <span className="header-values"> {this.state.Farm_No}</span> </h5>
<h5>Farmer No: <span className="header-values"> {this.state.Farmer_Reg_Number}</span> </h5>
<h5>Farmer Name: <span className="header-values"> {this.state.Farmer_Name} </span> </h5>
<h5>Village: <span className="header-values"> {this.state.Farmer_Village} </span> </h5>
<h5>Farm Area: <span className="header-values"> {this.state.Farm_Area} </span> </h5>
<br />
<table className="farmer-table">
<tr className="farmer-table-row">
<th className="farmer-table-header">Season</th>
<th className="farmer-table-header">Crop Name</th>
<th className="farmer-table-header">Crop Area</th>
<th className="farmer-table-header">Crop Type</th>
<th className="farmer-table-header">Estimated Quantity</th>
<th className="farmer-table-header">Organic Status</th>
<th className="farmer-table-header">Crop Total</th>
</tr>
{items}
</table>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.props.onHide}>Close</Button>
</Modal.Footer>
</Modal>
);
}
}
Upvotes: 0
Reputation: 11930
What I can make out of your code is that, when your DOM renders for the first time, this.props.values
doesn't exsist.
How about you try something like this
class MyVerticallyCenteredModal extends React.Component {
render() {
return (
<Modal
{...this.props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
dialogClassName="farmer-modal"
centered
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
DETAILS
</Modal.Title>
</Modal.Header>
<Modal.Body>
<h5>Farm No: <span className="header-values"> {this.props.values.Farm_No}</span> </h5>
<h5>Farmer No: <span className="header-values"> {this.props.values.Farmer_Reg_Number}</span> </h5>
<h5>Farmer Name: <span className="header-values"> {this.props.values.Farmer_Name} </span> </h5>
<h5>Village: <span className="header-values"> {this.props.values.Farmer_Village} </span> </h5>
<h5>Farm Area: <span className="header-values"> {this.props.values.Farm_Area} </span> </h5>
<br/>
<table className="farmer-table">
<tr className="farmer-table-row">
<th className="farmer-table-header">Season</th>
<th className="farmer-table-header">Crop Name</th>
<th className="farmer-table-header">Crop Area</th>
<th className="farmer-table-header">Crop Type</th>
<th className="farmer-table-header">Estimated Quantity</th>
<th className="farmer-table-header">Organic Status</th>
<th className="farmer-table-header">Crop Total</th>
</tr>
{
this.props.values.Crop_Details? (
this.props.values.Crop_Details.map((item, key) => (
<div>
<tr className="farmer-table-row">
<td className="farmer-table-data">{item.season}</td>
</tr>
</div>
))}): null }
</table>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.props.onHide}>Close</Button>
</Modal.Footer>
</Modal>
);
}
}
In the above code I a have used ternary operator to see if the this.props.values.Crop_Details
exist then only map it else to skip it (null) or as suggested by the other users in comment, try logging in render to see if this.props.values.Crop_Details
actually exist.
Upvotes: 1