1

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.

9
  • I am able to display all the table headers using this.props.values.xxxxx. But the map function over this.props.values.Crop_Details doesn't work and throws this error Commented Apr 21, 2019 at 6:43
  • 2
    Try console.log(this.props.values) before the loop see if the API call is actually there Commented Apr 21, 2019 at 6:48
  • Can you show the place in the code where you fetch the data? is that in componentDidMount? Commented Apr 21, 2019 at 6:50
  • you are not validating your data, you just assume everything is ok. This's breaking your application this.props.values.Crop_Details Commented Apr 21, 2019 at 6:52
  • Try { this.props.values.Crop_Details && this.props.values.Crop_Details.map( ) ..... } Commented Apr 21, 2019 at 6:57

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

but OP is saying he's fetching data in componentDidMount(), so this.props doesn't have values
@JuniusL. Exactly! If this.props doesn't have values then how can OP map over this.props.values.Crop_Details? ternary operator will only map when the data exist.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.