3

I am attempting to fetch data from this NHL API: https://statsapi.web.nhl.com/api/v1/people/8477474/

When I output the call to my page it returns undefined and I can't get it to display the value. Oddly enough, the first element in the object displays correctly but not any of the nested elements.

Here is my code:

import React, {Component} from "react"

class App extends Component {
constructor() {
    super()
    this.state = {
      loading: false,
      player: {}
    }
} 

componentDidMount() {
  this.setState({loading: true})
  fetch("https://statsapi.web.nhl.com/api/v1/people/8477474/")
    .then(response => response.json())
    .then(data => {
         this.setState({
           loading: false,
            player: data
         })
}) 

}

render() { 
  const fullname = this.state.loading ? "Loading..." : this.state.player.people[0].fullName; 
  return ( 
        <div>
            {fullname }
        </div> 
    )
}
}

export default App

This is not supposed to return undefined, because the key value is clearly there and I believe I am targeting it right.

I tried console logging but I also get undefined. I tried as well removing the [0] and doing this.state.player.people.fullName and all kinds of alternatives but no luck.

3 Answers 3

2

Set the initial state of loading to true, and remove the line this.setState({loading: true}).

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

8 Comments

I believe this solution is more optimal because you cut down on the number of rendering. Probably okay for now, but when your app becomes bigger, you will want to cut down on unnecessary rendering.
This is the only logical solution 👍
@JakeMartinez it also does not make sense to set loading to be false in the initial state given that your app breaks without the data from the endpoint.
true this solution is better. i set your answer as the correct one. thanks again.
No prob. Glad to be of help
|
1

There is a small amount of time where loading is false and the data isn't in player yet. Try the below

const fullname = Object.keys(this.state.player).length ? this.state.player.people[0].fullName:""

return ( 
    <div>
        {this.state.loading ? "Loading....": fullname }
    </div> 
)

Comments

0

You could initiate player state to null. Then use this line.

const fullname = this.state.player ? this.state.player.people[0].fullName:""

Or you could also do this with React Hooks if you wanted to as well.

https://codesandbox.io/s/baseball-fetch-api-30ehh?file=/src/App.js

import React, { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const [loading, setLoading] = useState(true);
  const [player, setPlayer] = useState();
  useEffect(() => {
    const fetchPeople = async () => {
      await fetch("https://statsapi.web.nhl.com/api/v1/people/8477474/")
        .then((res) => res.json())
        .then((res) => setPlayer(res))
        .then(() => setLoading(false))
        .catch((err) => setLoading(err));
    };
    fetchPeople();
  }, []);

  console.log(player);
  const fullname = player ? player.people[0].fullName : "";
  return <div className="App">{loading ? "Loading...." : fullname}</div>;
}

3 Comments

Also do you mind helping me to loop through like 100 players and display their names on the page? I tried a few ways but i'm looking for the most efficient method.
Sure. Share a code sandbox or something. You probably just have to map through the players. Something like players.map((player) => player.name)

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.