2

I am quite new to react and trying to fetch data from a .json file (called userData.json), but .map is not working even though userData is an array.

I already checked this by doing

 console.log(Array.isArray(userData));
console.log(typeof userData);

and it's giving back 'true' and 'object'.

Any idea what I am doing wrong? Here is the whole code snipped:

import React from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";

class JsonTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userData: [],
      error: undefined
    };
  }
  componentDidMount() {
    fetch("../data/userData.json").then(
      result => {
        this.setState({
          userData: result
        });
      },
      error => {
        this.setState({ error });
      }
    );
  }
  render() {
    const { userData } = this.state;
    console.log(Array.isArray(userData));
    console.log(typeof userData);
    return (
      <Paper>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>Name</TableCell>
              <TableCell>Foto</TableCell>
              <TableCell>Kategorie</TableCell>
              <TableCell>Kontaktinformation</TableCell>
              <TableCell>Job</TableCell>
              <TableCell>Notiz</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {userData.map(row => {
              return (
                <TableRow key={row.id}>
                  <TableCell component="th" scope="row">
                    {row.name}
                  </TableCell>
                  <TableCell>{row.image}</TableCell>
                  <TableCell>{row.category}</TableCell>
                  <TableCell>{row.contactInfo}</TableCell>
                  <TableCell>{row.job}</TableCell>
                  <TableCell>{row.note}</TableCell>
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </Paper>
    );
  }
}

export default JsonTable;
kind user
  • 40,029
  • 7
  • 67
  • 77
Nikolas Ch
  • 31
  • 1
  • 4

2 Answers2

1

but .map is not working even though userData is an array.

No. render() gets called two times. At the first time, the initial state gets rendered, userData is an empty array and you come to the conclusion that userData is an array. This time, mapping won't fail. Now the data gets fetched, and you call setState with userData being a response object (thats what fetch() resolves to), this time, Array.isArray will return false (but you somehow haven't seen that), and .map doesnt exist.

To parse the result of the fetch call and get an array, use .json():

 fetch("../data/userData.json")
   .then(res => res.json())
   .then(result => /*...*/)
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
1

Haven't you forgot to extract thejson body?

fetch("../data/userData.json")
  .then(
     (result) => result.json()
  )
     .then((userData) => {
        this.setState({
           userData,
        });
     })

Another thing - just in case - I would secure the possibiity that userData is not an array.

{Array.isArray(userData) && userData.map(row => { ... } }
kind user
  • 40,029
  • 7
  • 67
  • 77