Hareini Sreethi
Hareini Sreethi

Reputation: 59

Can't resolve the error Cannot read property 'map' of undefined in react js

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 all values are getting displayed but not crop_details

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

Answers (2)

Junius L
Junius L

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>
  );
 }
}

working example

Upvotes: 0

Alwaysblue
Alwaysblue

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

Related Questions