sandy
sandy

Reputation: 303

Unable to parse JSON data returned via fetch method in React

Before marking it duplicate would be great if you please read once. I really, searched on this. I am writing a React app to generate meme. I can connect the REST API successfully and able to fetch data. The problem is, while trying to parse data, I am getting an error which summarize that I am trying to access an undefined object, which I am not.

I tried same code statically (without React's rendering flavor) in another editor and it is working fine.

Here is my code,

class App extends React.Component{

    state = {memes : []};

    componentDidMount(){
        fetch(
            `https://api.imgflip.com/get_memes`

        ).then(
            (response) => {
                if(response.ok){
                    return response;
                }else{
                    console.log('no response');
                }
            }
        ).then(data => data.json()).then(data => {
            console.log(data); //This is getting printed fine
           // console.log(data.memes[1].name); //un-commenting this is throwing error that 'Cannot read property '1' of undefined'
            this.setState({memes:data.memes});


        });
 }
    render(){
        if(this.state.memes.length > 0){
            //For this I am getting error
            //Uncaught TypeError: Cannot read property 'length' of undefined
            console.log('array length is : ' + this.state.memes.length);
        }else{
            //This is printed fine
            console.log('Here array length is : ' + this.state.memes.length);

        }
        return (
            <div>
                <MemeImage/>
            </div>
        );
    }
}

export default App;

The problem is, during the second time rendering (after data is fetched) React assuming data.memes doesn't exist which is absurd for me. As per my console log, it exists. EX:

data:
memes: Array(100)
0: {id: "112126428", name: "Distracted Boyfriend", url: "https://i.imgflip.com/1ur9b0.jpg", width: 1200, height: 800, …}
1: {id: "87743020", name: "Two Buttons", url: "https://i.imgflip.com/1g8my4.jpg", width: 600, height: 908, …}
2: {id: "102156234", name: "Mocking Spongebob", url: "https://i.imgflip.com/1otk96.jpg", width: 502, height: 353, …}
3: {id: "129242436", name: "Change My Mind", url: "https://i.imgflip.com/24y43o.jpg", width: 482, height: 361, …}

I checked the demo data as below from the respective website. As per this, data.memes[0].name is perfectly valid. I tried it and it worked.

    {
    "success": true,
    "data": {
        "memes": [
            {
                "id": "61579",
                "name": "One Does Not Simply",
                "url": "https://i.imgflip.com/1bij.jpg",
                "width": 568,
                "height": 335,
                "box_count": 2
            }
    ]
    }
  }

But really, clueless what is happening during React rendering, that it is fetching the 'data' object but can't access properties inside. Any help regarding what I am failing to understand about React's rendering would be very much appreciated.

Upvotes: 1

Views: 1508

Answers (1)

Amol B Jamkar
Amol B Jamkar

Reputation: 1257

Use this code

this.setState({memes:data.data.memes});

When you console.log your data

console.log(data)

You get

{
 data: Object
 success: true
}

So you need to go inside data to access the memes,

Upvotes: 2

Related Questions