Samnan Rahee
Samnan Rahee

Reputation: 31

How to fix "TypeError: Cannot read property 'map' of undefined" in JavaScript?

I am fetching data from API and then mapping it to render into a table. But the fetching is not working and the state stays undefined when the page is loaded. Though the API is working fine and sending the data properly, I checked it both on Postman and my browser. How to solve this issue?

The page was crashing and I Googled a bit and added conditional rendering to stop it from crashing. But still cannot solve the issue with fetching data and mapping it.

Here is the code for the page that's not working:

import React, { Component } from "react";
import fetch from "isomorphic-unfetch";

export default class extends Component {
  static async getInitialProps() {
    const res = await fetch("https://linktoapi/path");
    const studentData = await res.json();
    return studentData;
  }
  componentWillMount() {
    this.setState({
      studentData: this.props.studentData
    });
  }

  render() {
    return (
      <table className="table is-striped is-fullwidth has-text-centered">
        <thead>
          <tr>
            <th>Name</th>
            <th>Class</th>
            <th>Section</th>
            <th>Batch</th>
            <th>Contact No.</th>
          </tr>
        </thead>
        <tbody>
          {this.state.studentData && this.state.studentData.map(studentDataRow => (
            <tr id={studentDataRow._id}>
              <td>{studentDataRow.name}</td>
              <td>{studentDataRow.class}</td>
              <td>{studentDataRow.section}</td>
              <td>{studentDataRow.batch}</td>
              <td>{studentDataRow.contact_no}</td>
            </tr>
          ))}
        </tbody>
      </table>
    );
  }
}

Here is the data from API:

[{"_id":"5d0cd67416c3a60017608a48","type":"student","name":"Samnan","contact_no":"9999","class":"123","section":"av","batch":"2002","__v":0},
{"_id":"5d0d1a7bfe72ac001775d778","type":"student","name":"as","contact_no":"0","class":"d","section":"r","batch":"a","__v":0},
{"_id":"5d0d1b24fe72ac001775d779","type":"student","name":"ab","contact_no":"0","class":"d","section":"afrgr","batch":"adsda","__v":0},
{"_id":"5d0d1b58259c5d6cd69acf3b","type":"student","name":"akash","contact_no":"567","class":"23","section":"h","batch":"2012","__v":0},
{"_id":"5d0ea1eb91eac20017f36739","type":"student","name":"as","contact_no":"08109209","class":"v","section":"qere","batch":"re","__v":0}]

To reproduce this issue locally:

git clone https://github.com/Geektrovert/EduSys.git && cd EduSys
npm i
npm run dev

and then go to http://localhost:3000/students

Upvotes: 1

Views: 769

Answers (1)

Oflocet
Oflocet

Reputation: 566

I changed a few things to get it to run. getInitialProps didn't seem to be called. I moved your API call in componentDidMount and use the state to store the student data.

import React, { Component } from "react";
import fetch from "isomorphic-unfetch";

export default class extends Component {

  constructor(props) {
    super(props);

    this.state = {
      studentData: []
    };
  }

  async componentDidMount() {
    const res = await fetch("https://edusys-yas.herokuapp.com/api/students");
    const studentData = await res.json();

    this.setState({ studentData });
  }
  render() {
    return (
      <table className="table is-striped is-narrow is-fullwidth">
        <thead>
          <tr>
            <th>Name</th>
            <th>Class</th>
            <th>Section</th>
            <th>Batch</th>
            <th>Contact No.</th>
          </tr>
        </thead>
        <tbody>
          {this.state.studentData.map(studentDataRow => (
            <tr>
              <td>{studentDataRow.name}</td>
              <td>{studentDataRow.class}</td>
              <td>{studentDataRow.section}</td>
              <td>{studentDataRow.batch}</td>
              <td>{studentDataRow.contact_no}</td>
            </tr>
          ))}
        </tbody>
      </table>
    );
  }
}

result

Upvotes: 2

Related Questions