2

I am new to React. My application uses Laravel and React.

When trying to display data received from an api call, I am getting the following error:

TypeError: this.state.userlist.map is not a function

The api call was successful and I am able to view the data from the response in the console (See screenshot below).

View.js

import React from 'react';
import axios from 'axios';

export class View extends React.Component{

constructor(props){
super(props);
this.state = {
  userlist: []
};
this.usersList = this.usersList.bind(this);
}

componentDidMount(){
axios.get('http://127.0.0.1:8000/api/test')
.then(res => {
  console.log(res.data);
  this.setState({ userlist: res.data });
})
.catch(error => console.log(error));
}

usersList(){
  this.state.userlist.map( (val,i) => {
    return(
  <tr>
    <td>{val.fname}</td>
    <td>{val.lname}</td>
    <td>{val.email}</td>
    <td>{val.phone}</td>
  </tr>
 )
})
}

render(){
return(
  <table>
    <thead>
      <tr>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Email</th>
        <th>Phone</th>
      </tr>
    </thead>
    <tbody>

    { this.usersList() }

    </tbody>
  </table>
)
}
}

Screenshot of error and response in the console

error image

3
  • The error tells you map is not a function - which suggests something is wrong with this.state.userlist. Why are you giving up there? What's wrong? Why do you understand or not understand about this situation? Use your debugger or add some log statements or something to do some basic debugging. Commented Oct 21, 2020 at 14:02
  • usersList(){ console.log(this.state.userlist) // put here a console.log to see that's in this.state.userlist. Commented Oct 21, 2020 at 14:06
  • are you sure userlist is array??they error occurs when you have not mapped the array Commented Oct 21, 2020 at 14:11

6 Answers 6

1

You have to put res.data.data to setState

Example: this.setState({ userlist: res.data.data });

an Array with data you need is inside res.data

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

Comments

1

Please find a working example with dummy data for illustrative purposes.

import React from "react";

const users = [
  { fname: "J", lname: "Smith", email: "[email protected]", phone: "12345" },
  { fname: "S", lname: "Joe", email: "[email protected]", phone: "6789" }
];

export default class View extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userlist: []
    };
  }

  componentDidMount() {
    this.setState({ userlist: users });
  }

  render() {
    return (
      <table>
        <thead>
          <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
            <th>Phone</th>
          </tr>
        </thead>
        <tbody>
          {this.state.userlist.map((val, i) => {
            return (
              <tr>
                <td>{val.fname}</td>
                <td>{val.lname}</td>
                <td>{val.email}</td>
                <td>{val.phone}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    );
  }
}

 Working Example

Comments

1

I got my answer. But I want to map rows in different function and then want to call that function within table. As I did in my posted question.

import React from 'react';
import axios from 'axios';

export class View extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      userlist: [],
    };
  }

  componentDidMount() {
    axios.get('http://127.0.0.1:8000/api/test')
      .then(res => {
        console.log(res.data);
        this.setState({ userlist: res.data.data });
      })
      .catch(error => console.log(error));
  }

  render() {
    const { userlist } = this.state;
    return (
      <table>
        <thead>
          <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
            <th>Phone</th>
          </tr>
        </thead>
        <tbody>

          {userlist.length > 0 ?
            userlist.map((val, index) => {
              return <tr key={index}>
                <td>{val.fname}</td>
                <td>{val.lname}</td>
                <td>{val.email}</td>
                <td>{val.phone}</td>
              </tr>;
            }) : null
          }
        </tbody>
      </table>
    );
  }
}

Comments

0

here is the solution

import React from 'react';
import axios from 'axios';

export class View extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      userlist: [],
    };
  }

  componentDidMount() {
    axios.get('http://127.0.0.1:8000/api/test')
      .then(res => {
        console.log(res.data);
        this.setState({ userlist: res.data });
      })
      .catch(error => console.log(error));
  }

  render() {
    const { userlist } = this.state;
    return (
      <table>
        <thead>
          <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
            <th>Phone</th>
          </tr>
        </thead>
        <tbody>

          {userlist.length > 0 ?
            userlist.map((val, index) => {
              return <tr key={index}>
                <td>{val.fname}</td>
                <td>{val.lname}</td>
                <td>{val.email}</td>
                <td>{val.phone}</td>
              </tr>;
            }) : null
          }
        </tbody>
      </table>
    );
  }
}

1 Comment

I don't want to do map data in table. I want to make a function and call that function within table to show rows. As I worked in my code.
0

I have also encountered same issue several times before, the one and only solution that worked for me was to replace {} with (). i.e.

{userlist.length > 0 ?
            userlist.map((val, index) => (
              return <tr key={index}>
                <td>{val.fname}</td>
                <td>{val.lname}</td>
                <td>{val.email}</td>
                <td>{val.phone}</td>
              </tr>;
            )) : null
          }

Notice the use of ( instead of { after userlist.map((val, index) => . This should fix your error.

1 Comment

./src/component/View.js Line 25:9: Parsing error: Unexpected token 23 | usersList(){ 24 | this.state.userlist.map( (val,i) => ( > 25 | return( | ^ 26 | <tr key={i}> 27 | <td>{val.fname}</td> 28 | <td>{val.lname}</td>
0

You can use Short-Circuit operator (&&) to conditionally check if the data exists and then fetch it like this

usersList(){
  this.state.userlist && this.state.userlist.map( (val,i) => {
    return(
  <tr>
    <td>{val.fname}</td>
    <td>{val.lname}</td>
    <td>{val.email}</td>
    <td>{val.phone}</td>
  </tr>
 )
})
}

The reason this is required because the data fetching process from API is asynchronous and it might take some time and before that, your program reaches usersList() and throws that error.

So here, you are conditionally checking first using && and if data exists from API then you call this logic.

2 Comments

./src/component/View.js Line 37:13: 'userlist' is assigned a value but never used no-unused-vars
Are you getting this warning inside userList() ? Are you assigning userlist variable anywhere else apart from state? You can try this.state.userlist.length >0 && this.state.userlist.map()

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.