1

Trying to fetch data from the NHL API, using React Hooks.

Link to CodeSandbox.

When I comment out the tag and it's content in the return statement, my console log does fetch the API successfully. However, I'm getting an error in the console when the tag's content (the .map statement), saying "Cannot read property 'map' of undefined".

Trying to figure out why this error is displaying, and why I can't map the data defined from the API.

App.JS

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import axios from "axios";

import "./styles.css";

function App() {
  const [data, setData] = useState({ people: [] });
  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        "https://statsapi.web.nhl.com/api/v1/people/8475166?expand=person.stats&stats=yearByYear,careerRegularSeason&expand=stats.team&site=en_nhlCA"
      );
      setData(result.data.people);
      console.log(result.data.people);
    };
    fetchData();
  }, []);

  return (
    <ul>
      {data.people.map(item => (
        <li key={item.objectID}>
          <p>{item.id}</p>
          <p>{item.primaryNumber}</p>
        </li>
      ))}
    </ul>
  );
}

export default App;

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

2 Answers 2

4

I guess it should be

setData({ people: result.data.people });

You're setting the data in an object property called people in your state variable.

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

Comments

1

The problem is with setData(result.data.people) !

The initial state which you provide is quite different from the way you set data.

Initial state: data = {people: []} (So now you can map like : data.people)

In use effect: data = result.data.people

So the solution is either you change the initial state and then change how to loop.

const [data, setData] = useState([]);  // Line #8

setData(result.data.people);  // Line # 14
                              // Line # 22
{data.map(item => (    
 <li key={item.objectID}>
   <p>{item.id}</p>
   <p>{item.primaryNumber}</p>
 </li>
))}

or you can change the way you assign after fetching the result.

setData({people: result.data.people})

I would have personally favored the first solution as I do not see any reason to have data being Object. Or I could have simply called it "people" 😉

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.