Error while indexing data from this.setState()

162 Views Asked by At

I am creating a GIF search web app with the GIPHY API and react.

After I fetch the data from the API, I can index the data console.log(json.data[0])

.then((json) => {
      console.log(json.data[0]);
      this.setState({ myGif: json });
});

But when I set my state to the JSON file and I try to index the data console.log(this.state.myGif.data[0]) I get an error

TypeError: Cannot read property “0” from undefined

    render() {
        console.log(this.state.myGif.data[0]);
        return (
            <div>
                <h1>This is </h1>
            </div>
        );
    }

I would really appreciate getting a response

Below is the full code of the component

import React, { Component } from 'react';

export class Content extends Component {
    constructor(props) {
        super(props);

        this.state = {
            myGif: {},
        };
    }

    componentDidMount() {
        const api_key = 'rYJ5AxF8DXFqeX8ub81fbuje3J12lrh6';
        fetch(
            `http://api.giphy.com/v1/gifs/search?q=ryan+gosling&api_key=${api_key}&limit=3`
        )
            .then((response) => response.json())
            .then((json) => {
                console.log(json.data[0]);
                this.setState({ myGif: json });     
            });
    }

    render() {
        console.log(this.state.myGif.data[0]);
        return (
            <div>
                <h1>This is </h1>
            </div>
        );
    }
}

export default Content;
5

There are 5 best solutions below

1
macborowy On BEST ANSWER

Try to console.log data like:

console.log(
      this.state.myGif.data
        ? this.state.myGif.data[0]
        : "data is not downloaded yet"
    );
0
Murat Karagöz On

Your fetch and setState calls are both asynchronous. While it is fetching your render will already be called.

One way to fix this is to check for the current state e.g.

 render() {
        this.state.myGif && console.log(this.state.myGif.data[0]);
        return (
            <div>
                <h1>This is </h1>
            </div>
        );
    }
1
Ryuko On

It's because when the first time the component is rendered, this.state.myGif.data does not exist, because the initial state of the myGif is just empty. You should check if the data is loaded ...

console.log(this.state.myGif.data ? this.state.myGif.data[0] : "Loading •••");
0
Asutosh On

import React, { Component } from 'react';

export class Content extends Component {
    constructor(props) {
        super(props);

        this.state = {
            myGif: {data:["Image is getting Loaded"]},
        };
    }

    componentDidMount() {
        const api_key = 'rYJ5AxF8DXFqeX8ub81fbuje3J12lrh6';
        fetch(
            `http://api.giphy.com/v1/gifs/search?q=ryan+gosling&api_key=${api_key}&limit=3`
        )
            .then((response) => response.json())
            .then((json) => {
                console.log(json.data[0]);
                this.setState({ myGif: json });     
            });
    }

    render() {
        console.log(this.state.myGif.data[0]);
        return (
            <div>
                <h1>This is </h1>
            </div>
        );
    }
}

export default Content;

0
Justsolarry On

You don't need json().

componentDidMount() {
        const api_key = 'rYJ5AxF8DXFqeX8ub81fbuje3J12lrh6';
        fetch(
            `http://api.giphy.com/v1/gifs/search?q=ryan+gosling&api_key=${api_key}&limit=3`
        )
            .then(response => {
                const data = response.data
                this.setState(data);     
            });
    }

Then in your render function you can console.log(this.state) to see your entire state. It's an array of objects so you'll need to map it out if you want to display all of them. You can map like this :

this.state.data.map((item,i) => <li key={i}>Test</li>)

Since data in your state may be undefined on the first render. You'll want to set a default value of [] for this.state.data

If you want to display the first one you can say this.state && this.state[0].type