1

I am trying to render the response of a simple api I've created but when I try to iterate through the items, it comes as undefined. I know it has to do with asynchronous programming but can't figure out how to solve it. Could anybody help ?

import React from 'react';

export default class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            items: undefined
        };
    }
    componentDidMount() {
        fetch('https://petzie-cajuhqnpqy.now.sh/breeds')
        .then(res => res.json())
        .then(data => {
            this.setState(() => {
                return {
                    items: data.result
                };
            });
            console.log(this.state);
        })
        .catch(err => console.log(err));
    }
    render() {
        return (
            <div>    
                { this.state.items.map((item) => {
                    return <p>{item.name}</p>;
                }) }         
            </div>
        );
    }
}

0

2 Answers 2

1

First of all, if you are going to .map through this.state.items, it can't be undefined at any point, otherwise you will throw an error (.map expects an array). So, in your constructor, define it as an empty array:

constructor(props) {
    super(props);
    this.state = { items: [] };
}

Second, setState is async. Therefore, when you call setState and this.state right after it, the object was not updated yet. But because of React nature, whenever it gets updated, your render function will be called again and this time this.state.items will have the data fetched from the API.

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

2 Comments

Thanks a lot Rafael, that was the only change I had to make in order to have it work. And thanks for the setState advice also. Cheers !
You're welcome. Please just accept the answer for future reference.
0

If you have async calls you need to do something like this:

render() {
    if(!this.state.items) { 
        return <div></div> 
    }
    return (
        <div>    
            { this.state.items.map((item) => {
                return <p>{item.name}</p>;
            }) }         
        </div>
    );
}

Is one way to do it.

2 Comments

You forgot the ! before this.state.items. Anyways this is not necessary if you initially set this.state.items to []. A call to map() on an empty array will not do anything.
Thanks for the hint. Yes, that also possible

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.