Search code examples
reactjsreact-hooksjavascript-objectsuse-effect

TypeError: can't convert undefined to object In React


I'm able to fetch the data from API, but not able to set the data into react state variable. Using useEffect. It's Weird because Initially Code was working fine, I was able to set the data into state variable, but after writing bunch of code. I'm getting this error.

App.js


const fetchData = async () => {
    try {
        const response = await axios.get(
            "https://60d007f67de0b200171079e8.mockapi.io/bakery"
        );
        const { data } = response;
        return data;
    } catch (err) {
        console.error(err)
    }

};

const extractData = (bakerys) => {
    const bakery = bakerys[0];
    const header = [];

    Object.keys(bakery).forEach((objKeys) => {
        const value = bakery[objKeys];
        //  if(type of value !==  'object'){
        header.push(objKeys);
    })

    return header;
};

export default function App() {
    const [bakerys, setBakerys] = useState([]);
    const [flatbakery, setFlatbakery] = useState([]);

    useEffect(() => {
        fetchData().then((randomData) => {

            console.log('randomData ->', randomData) // able to console data as an Array of object

            setBakerys(randomData); // Not able to set the randomData into state variable
            console.log('bakerys', bakerys)

        })

    }, []);

    useEffect(() => {
        setFlatbakery(extractData(bakerys));
    }, [bakerys]);

    return (
        <div className="App">
            <h1>Hello CodeSandbox</h1>
            <h2>Edit to see some magic happen!</h2>
            <table>
                <thead>
                    <tr>
                        {flatbakery.map((headers, idx) => (
                            <th key={idx}>
                                {headers}
                            </th>
                        ))
                        }
                    </tr>
                </thead>
            </table>
        </div>
    );
}

Output enter image description here


Solution

  • This case would come up when your bakerys array is empty, that is bakerys[0] is essentially undefined. You probably need to add some sort of check before you try to iterate the keys of it.

    const extractData = (bakerys) => {
        const bakery = bakerys[0];
        const header = [];
    
        if(bakery) { // only run the following block if bakery is not undefined(or falsey)
        Object.keys(bakery).forEach((objKeys) => {
            const value = bakery[objKeys];
            //  if(type of value !==  'object'){
            header.push(objKeys);
        })
        }
    
        return header;
    };
    

    EDIT: It appears I have forgotten to mention WHY bakerys may be empty initially. UseEffect runs when the component mounts as well, so the first time that it is called, bakerys is still an empty array. As subsequent updates are made to it, it will eventually be populated with data, so you should always attempt to check if the value has been populated before attempting to run any operations on it.