MUHAMMAD ZAIN
MUHAMMAD ZAIN

Reputation: 39

`object' is undefined due to async function that fetched data in useEffect hook in reactjs

I am fetching an object from api using axios.get("url"). The object fetched successfully (in Animal state) but there is a component level state (imageState) which requires updation using setState with fetched data.
Code:
Component:

import React,{useEffect, useState} from 'react'
import axios from 'axios'
const AnimalDetail = ({match}) => {
    const [Animal ,setAnimal ] = useState({})
    const Id = parseInt(match.params.id)
    const [imageState, setImageState] = useState ("");
 
useEffect(()=>{
            const fetchAnimal = async () => {
                const {data} = await axios.get(`/api/animals/${Id}`)
                setAnimal(data)
            }
            fetchAnimal()
            // setImageState(Animal.image[0])   // need to access first index of image object
    },[])

    useEffect(()=>{

   setImageState(Object.values(Animal.image)[0])  // error cant convert undefined to object
}
   
    return (
        <>
       <h2>imageState </h2>  //undefined
        <h2>{typeof(Animal.image)}</h2>  //gives object
       </>
  )
}
export default AnimalDetail


Backend Api :

{"id":2,
"image":["/image.jpg","/image2.jpg"],
"price":60000,
"breed":"",
"isAvailable":true,
"weight":110,
}

How can i fetch the data and update the component level state periodically(after fetching)?

Upvotes: 0

Views: 567

Answers (2)

Shubham J.
Shubham J.

Reputation: 646

You can try following, maybe this can help you. Removed the second useEffect and updated the image state in the first useEffect.

And also I can see, you have declared const [imageState, setImageState] = useState (""); twice. You can remove the second one.

Also, make sure you handle the API error in useEffect otherwise this may break the application on API failure.

import React, { useEffect, useState } from 'react';
import axios from 'axios';
const AnimalDetail = ({ match }) => {
  const [Animal, setAnimal] = useState({});
  const Id = parseInt(match.params.id);
  const [imageState, setImageState] = useState('');

  useEffect(() => {
    const fetchAnimal = async () => {
      const { data } = await axios.get(`/api/animals/${Id}`);
      setAnimal(data);
      setImageState(data.image[0]);
    };
    if (Id) {
      fetchAnimal();
    }
  }, [Id]);

  return (
    <>
      <h2>imageState </h2> //undefined
      <h2>{typeof Animal.image}</h2> //gives object
    </>
  );
};
export default AnimalDetail;

Upvotes: 3

Vahid18u
Vahid18u

Reputation: 403

your code has some error in the second useEffect. you can use this one :

     useEffect(() => {
if (Animal) setImageState(Object.values(Animal.image)[0]); // error cant convert undefined to object
      }, [Animal]);

this is because the Animal should have value first. and you are defining imageState two times in your code! the first one is enough.

Upvotes: 2

Related Questions