0

I am trying to fetch some data from google's firestore in an useEffect, and saving it in useState variable

useEffect(() => {
    const fetchFirst = async () => {
        ...
        // setting the new found data in a useState
        setData1(data1)
    }
    fetchFirst()
}, [])

Now, I want to fetch some other data from firestore, but this data requires some information from previous fetched (fetchFirst) data. I tried to do this but does not work

useEffect(() => {
    const fetchFirst = async () => {
        ...
        // setting the new found data in a useState
        setData1(data1)
    }
    const fetchSecond = async (data1) => {
        ...
        // setting the new found data in a useState
        setData2(data2)
    }
    fetchFirst()
    fetchSecond(data1)
}, [])

My first fetch works completely fine, but when my code reaches the second fetch, the input data (data1) is null. Can someone please help me figure it out. Thanks

Jam Dos
  • 119
  • 1
  • 2
  • 6

3 Answers3

1

Both function are async. You need to call fetchSecond when data1 value changes:

useEffect(() => {
    const fetchFirst = async () => {
        ...
        // setting the new found data in a useState
        setData1(data1)
    }
    fetchFirst()
}, []);


useEffect(() => {
    const fetchSecond = async (data1) => {
        ...
        // setting the new found data in a useState
        setData2(data2)
    }
    fetchSecond(data1)
}, [data1]);

Or call fetchSecond inside then block

useEffect(() => {
    const fetchFirst = async () => {
        ...
        // setting the new found data in a useState
        setData1(data1);
        return data1 //--> return data value
    }
    const fetchSecond = async (data1) => {
        ...
        // setting the new found data in a useState
        setData2(data2)
    }
    fetchFirst().then(data => fetchSecond(data));
    
}, []);
lissettdm
  • 12,267
  • 1
  • 18
  • 39
1

If your using async you should wait, with the await keyword, for the first fetching to finish, then use its result in the fetchSecond:

useEffect(() => {
  const fetchFirst = async (): SomeData => {
    const data = await fetch(...);
    return data;
  };

  const fetchSecond = async (data: SomeData) => {
    await fetch(...);
  };

  const fetchAllData = async () => {
    const data = await fetchFirst();
    await fetchSecond();
  };

  fetchAllData();
}, []);
PierreB
  • 489
  • 3
  • 14
0

You can simply call your second inside your first function call and pass data that you're setting in the state rather than passing state data.

useEffect(() => {
    const fetchFirst = async () => {
        ...
        // calling the function with new found data
        fetchSecond(data1)

        // setting the new found data in a useState
        setData1(data1)
    }
    const fetchSecond = async (data1) => {
        ...
        // setting the new found data in a useState
        setData2(data2)
    }
    fetchFirst()
}, [])
Brijesh Dhanani
  • 856
  • 4
  • 12