Home > Mobile >  How to Use Helper Function that Calls an API to Work Inside of UseEffect Hook
How to Use Helper Function that Calls an API to Work Inside of UseEffect Hook

Time:06-11

I am new to ReactJS and am struggling on getting the useEffect to work properly. The below code works just fine:

const [expenditureItems, setExpenditureItems] = useState([]);

    useEffect(() => {
    async function getExpenditureItems() {
      const financeUrl = "http://blah.blah.blah/blah";
      const filter = {"type": "Expenditure"}
      const response = await axios.post(financeUrl, filter);
      setExpenditureItems((Array.from(response.data)));
    }
    getExpenditureItems();
}, []);

However, I already have this same function defined in a helper file here and would rather not repeat code or have another place where the URL is defined:

import axios from 'axios';

const financeUrl = "http://blah.blah.blah/blah";
let response = ''

async function getDocuments(filter=null) {
if(!filter) {
    response = await axios.get(financeUrl);
}
else {
    response = await axios.post(financeUrl, filter);
}
console.log(response.data);
return Array.from(response.data);}

...More Stuff Here...

export {getDocuments, createDocument, updateDocument, deleteDocument}

I know the helper method itself is working correctly and the data returned looks exactly like the data that is returned without the use of the helper method. Here is what I've tried so far based on what I read here: https://www.benmvp.com/blog/helper-functions-react-useeffect-hook/

    useEffect(() => {
    const filter = {"type": "Expenditure"}
    setExpenditureItems(getDocuments(filter));
}, []);

I also tried this thinking maybe async was required in the useEffect since the underlying function was async:

    useEffect(() => {
    async function getExpenditureItems() {
      const filter = {"type": "Expenditure"}
      setExpenditureItems(getDocuments(filter));
    }
    getExpenditureItems();
}, []);

I tried using the useCallback method described in that link as well, but nothing seems to work. I'm sure I'm missing something simple here or there is something I don't understand about how useEffect works that's preventing this from working. Any ideas?

CodePudding user response:

The hint in your last attempt is that you made the function async, but nowhere in that function do you await anything.

getDocuments returns a Promise. You need to await it:

useEffect(() => {
  async function getExpenditureItems() {
    const filter = {"type": "Expenditure"}
    const documents = await getDocuments(filter);
    setExpenditureItems(documents);
  }
  getExpenditureItems();
}, []);

Or even just:

useEffect(() => {
  async function getExpenditureItems() {
    setExpenditureItems(await getDocuments({"type": "Expenditure"}));
  }
  getExpenditureItems();
}, []);

CodePudding user response:

Hey Chopps, looks like you need to await the getDocuments helper function, otherwise you are trying to set the state with a Promise. In your first example it was not happening because you were already awaiting the Promise to be resolved const response = await axios.post(financeUrl, filter);

useEffect(() => {
  const filter = {"type": "Expenditure"}
  setExpenditureItems(await getDocuments(filter));
}, []);
  • Related