OldDew
OldDew

Reputation: 67

Variable doesn't initialize after async function

I am making a request like this:

    const createProgramari = async () => {
        let prog = [];
        try {
            await axios.get('http://localhost:8000/api/programariByDentistID', {
                params: {
                    id: JSON.parse(localStorage.getItem('user'))["id"]
                }
            })
                .then(function (res) {
                    console.log(res);
                    if(res.status === 200) {
                        prog = res.data;
                    }
                })
                .catch(function (error) {
                    console.log(error);
                });
            setProgramari(prog);
        } catch(e) {
            console.log(e);
        }
    }

If I try to see this in my useEffect the variable 'programari' is an empty array (the value I initialized it with)

    const [programari, setProgramari] = useState([]);

    useEffect( () => {
        // code to run on component mount
        createProgramari();
        console.log(programari);
    }, [])

I tried printing the response and axios gets it right. What am I doing wrong? Is there a place I could learn how to not do the same mistake?

Upvotes: 0

Views: 306

Answers (4)

HardCoreQual
HardCoreQual

Reputation: 391

in useEffect programari is equal with [] because setProgramari() not update already existed state in current component version, if set new state for programari, this modification propagate rerendering component

console.log(programari) work with current component state version

if you want dump programari you can move console.log outsite useEffect in this case you get in console two dump - [] for first version and [ withData ] for version what rerender because setState()

or if you want use data from axios in useEffect you can return it how promise

Upvotes: 0

Ron B.
Ron B.

Reputation: 1540

The way you wrote the function is very confusing, I'd suggest refactoring this to

const createProgramari = async () => {
    try {
        const prog = (await axios.get('http://localhost:8000/api/programariByDentistID', {
            params: {
                id: JSON.parse(localStorage.getItem('user'))["id"]
            }
        })).data;
        setProgramari(prog);
    } catch (e) {
        console.log(e)
    }
}

Upvotes: 1

Polish
Polish

Reputation: 466

To view data you can do something like this:

useEffect(() => {
   createProgramari()
     .then((someReturnedDataFromAPI) => { // Promise returned
       console.log(programari)
     })
 }, []) // Initialization

Upvotes: 0

jaybhatt
jaybhatt

Reputation: 547

The salient point here is that setProgramari is async in nature. If it is called, it doesn't necessarily imply that it will be executed right away. One way you can handle this is follows.


useEffect(() => {
  createProgramari();
}, []);

// consider useMemo or useCallback based on your use case if need be
useEffect(() => {
  // whatever logic you want to have
  console.log(programari); // will get new value always
}, [programari])

Upvotes: 3

Related Questions