Using state with componentDidMount

65 Views Asked by At

I want to fetch data that returns successfully after componentDidMount, but before there is an error that singer.data is undefined:

// imports
export default class LookSinger extends Component {
    state = {
        singer: {}
    }
    componentDidMount () {
        let { singer } = this.props.location.state;
        singer = singer.replace(/ /g,"+");
        const fetchData = async () => {
        try {
            const response = await fetch(
                `http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=${singer}&api_key=a3c9fd095f275f4139c33345e78741ed&format=json`
            );
            const data = await response.json();
            this.setState({
                singer: data
            })
          } catch (error) {
            console.log(error.message);
          }
        }
        fetchData();
    }
      render() {
          let singer = this.state.singer
        return(
            <div>
                {console.log(singer.artist.name)} // gives undefined but after fetching artist.name absolutely exists
            </div>
        )
      }
}

Url is:http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=Ariana+Grande&api_key=a3c9fd095f275f4139c33345e78741ed&format=json

3

There are 3 best solutions below

0
On BEST ANSWER

The problem is here:

{console.log(singer.artist.name)}

In the initial render, singer.artist is undefined and if you call singer.artist.name it will throw error. name of undefined.... You just need to wait for data to fetch and update the state.

Try like this

export default class LookSinger extends Component {
  state = {
    singer: {}
  }
  componentDidMount () {
    let { singer } = this.props.location.state;
    singer = singer.replace(/ /g,"+");
    const fetchData = async () => {
    try {
        const response = await fetch(`http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=${singer}&api_key=a3c9fd095f275f4139c33345e78741ed&format=json`);
        const data = await response.json();
        this.setState({ singer: data })
      } catch (error) {
        console.log(error.message);
      }
    }
    fetchData();
  }
  render() {
    const { singer } = this.state
    if (!singer.artist) { // <-- Check if the data is present or not.
      return <div>Loding singer info...</div>
    }
    return(
      <div>
        <h1>{singer.artist.name}</h1>
      </div>
    )
  }
}
1
On

You do let singer = this.state but there's no this.setState({ singer: ... }) in your code. Instead of this.setState({ data }), try this.setState({ singer: data })

3
On

Set you state as below and,

        const data = await response.json();
        this.setState({
            singer: data
        })

and you can log it out likes this,

        console.log(this.state.singer)