Home > OS >  Get data from async function and update state
Get data from async function and update state

Time:04-17

I have created a variable using useState and that is an empty array.

const [data, setData] = useState([]);

I am calling an async function inside useEffect that is helping me to get all the data and update the data when received

useEffect(() => {
    //
    const items = [];
    async function fetchData() {
      items = await getAllItems();   //it should wait for data and then setData
      setData(items);    
    }
    fetchData();
    console.log("from useEffect", items);  // still items array is empty
  }, []);

Here is my imported data retrieving function which uses Axios and returns the data:

export const getAllItems = async () => {
  const url = baseUrl   "/items/getAllItems";
  await axios({
    method: "GET",
    withCredentials: true,
    url: url,
  }).then((res) => {
    return res;  // when console logged we get a proper array if data
  });
};

But nothing works all I am getting back is object of promise. Could anyone guide me what I am missing out in my code?

CodePudding user response:

You are assigning the value of getAllItems() to a constant variable items that has already been declared here:

const items = [];

However, as per the mdn web docs:

The value of a constant can't be changed through reassignment (i.e. by using the assignment operator), and it can't be redeclared (i.e. through a variable declaration).

So you need to either initialize that variable using let, or better yet assign it immediately as follow:

const items = await getAllItems();

You can then get rid of const items = [];

CodePudding user response:

You didn't return the data from the axios call.

export const getAllItems = async () => {
  const url = baseUrl   "/items/getAllItems";
  const { data } = await axios({
    method: "GET",
    withCredentials: true,
    url: url,
  });
  return data;
};

CodePudding user response:

Your console.log() is in the wrong position (2). Should be in the position marked with (1) instead. Please check the comments I added:

useEffect(() => {
    const items = [];
    async function fetchData() {
      items = await getAllItems();   //it should wait for data and then setData
      setData(items);
      // (1) you chould console.log() the items array here instead
      // if the data is properly returned from getAllItems() it will be visible here
      console.log("from useEffect", items);
    }
    fetchData();
    console.log("from useEffect", items);  // (2) items array will be empty here right after fetchData() as getAllItems() has not returned yet.
  }, []);

CodePudding user response:

useEffect(() => {
   let isMounted = true 
   function fetchData() {
      const items = axios.get(baseUrl   "/items/getAllItems")
      if (isMounted) setData(items);    
   }
   fetchData();
   return () => {isMounted = false}
}, []);
  • Related