3

This is my code in codepan: https://codesandbox.io/s/relaxed-drake-4juxg?file=/src/Persons/persons.jsx

I don't have any idea why it is throwing an error that cannot read property data of undefined when sometimes it is reading it!

I have created a json file in my public folder:

[
  {
    "id": 0,
    "name": "John",
    "lastName": "Doe",
    "address": "Main Street",
    "gender": "male",
    "country": "USA",
    "city": "LA"
  },
  {
    "id": 1,
    "name": "Michael",
    "lastName": "Zeburgee",
    "address": "Second Street",
    "gender": "male",
    "country": "Germany",
    "city": "Hamburg"
  },
  {
    "id": 3,
    "name": "Julia",
    "lastName": "Hleb",
    "address": "St.Patric",
    "gender": "female",
    "country": "Belarus",
    "city": "Minsk"
  },
  {
    "id": 4,
    "name": "Petar",
    "lastName": "Pan",
    "address": "Some Street",
    "gender": "male",
    "country": "UK",
    "city": "London"
  }
]

I have an axios request:

import axios from "axios";

export default async function getPersonsInfo() {
  const response = await axios.get("persons.json");
  return response;
}

There is a Persons component:

import React, { useState } from "react";
import { useQuery } from "react-query";
import getPersonsInfo from "../api/personCalls";

export default function Persons() {
  const [persons, setPersons] = useState([]);
  const { data: personsData, status } = useQuery(
    "personsData",
    getPersonsInfo,
    {
      onSuccess: () => {
        setPersons(personsData.data);
      },
      onError: (error) => {
        console.log(error);
      }
    }
  );

  return (
    <>
      {status === "loading" ? (
        <div>Loading ... </div>
      ) : (
        <div>
          {persons.map((person) => (
            <div>
              <p>{person.name}</p>
              <p>{person.lastName}</p>
              <p>{person.address}</p>
              <p>{person.gender}</p>
              <p>{person.country}</p>
              <p>{person.city}</p>
            </div>
          ))}
        </div>
      )}
    </>
  );
}

The problem is that it cannot read the data, but if I console.log(personsData) there is data.

onSuccess: () => {
        setPersons(personsData.data);
      },

You can see in the codepan. First when you open the file it is Loading... and fetching the data, but once you refresh the page it cannot!

4
  • 1
    you don't need a state, useQuery already manages the state. Just use data: personData directly. Commented Feb 1, 2021 at 16:30
  • Could you update the code, because something is wrong again, there is an error that personsData.map is not a function. Commented Feb 1, 2021 at 16:52
  • The data is not an array before the query is complete, so you have to provide some kind of default state that takes this into account, like (data || []).map(/* ... */) Commented Feb 1, 2021 at 16:59
  • So why am I using this ternary operator {status === "loading" ? <div>Loading ...</div> : (/* ... */), if it is executing it even if it's not complete!? And again I could not run it properly, even I could not get the idea. Do you mean (peronData || []).map ? cause there is an error again. Commented Feb 1, 2021 at 17:08

1 Answer 1

1

Just get the data from the onSuccess callback:

onSuccess: (data) => {
        console.log('data',data)

See the data logged, then use setPersons to set data you need to the state.

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

1 Comment

Could you update my code in codepan, because it is throwing an error that personsData.map is not a function ....

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.