0
const loadData = async () => {
        try {
            const data = await GetAllForms();
            setAllForms([...data]);
        } catch (err) {
            console.log(err);
        }
    }

My variable data is receiving the data from GetAllForms (that is a promisse function), but when I try to assign to another variable is empty, In this console log for example is showing a empty array. But if i but a console.log(data) the data appears correctly, the problem is only with the dataAux I dont have a clue what is going on here. Thanks!

Here the GetAllForms

export async function GetAllForms() {
    const formRef = await dbForms.collection("forms");
    const snapshot = await formRef.get();
    const dataFormattedArray = [] as IFormsFormatted[];

    snapshot.forEach(async doc => {
        const docData = doc.data() as IForms
        const aux = [] as FormsData[];

        for (const id of docData.formsFieldId) {
            const test = await GetOneFormsField(id);
            aux.push(test);
        }

        const dataFormatted = { ...docData, formsFieldId: [...aux] }

        dataFormattedArray.push(dataFormatted);
    })
    
    return dataFormattedArray;
}

If i check de allForms variable after the setAllForms, is empty.

  • Is `GetAllForms()` actually returning an array? Side note - you don't have to spread `dataAux` when passing it in setAllForms(). It's already been spread and you're not mutating state with it. (I'm also assuming you're going to do something more with dataAux there than just console.log it). – squillman Oct 01 '21 at 20:55
  • 2
    It's not really clear why you're making so many copies. Can't you just `setAllForms(data)`? – Andy Oct 01 '21 at 20:56
  • 1
    Your `getAllForms` is likely the issue, can you show the code for this.? – Keith Oct 01 '21 at 20:59
  • 1
    This means that GetAllForms or some other thing that is responsible for modifying data is messed up and results in race condition, i.e. something happens after GetAllForms promise is resolved. GetAllForms is essential for the problem, and the question doesn't contain it. – Estus Flask Oct 01 '21 at 23:01
  • I put the dataAux only to see if if the assignment is occurring correctly. Only for debug propose. Yes the GetAllForms is returning a array – Adrian Valdes Oct 03 '21 at 02:29
  • I suspect that it's because you`async await` with `forEach`. Could you try changing it to just a simple `for loop`? `forEach` doesn't wait for an async function to be finished. So, `dataFormattedArray` was returned from `GetAllForms` before it's populated. – Bhoomtawath Plinsut Oct 03 '21 at 02:46
  • But, when I log the `data` before the `setAllForms`, its returning the right data format that I expect. – Adrian Valdes Oct 03 '21 at 05:07
  • I tested a log without the spread operator and the log of the `allforms`` after the `loadData` was correct, but the component is not re-rendering, i suspect that is because i pass the same array on the `setAllForms`, and the useState interpret that isnt have change any value. I think the problem is with the spread operator, but i dont know why, and how bypass this – Adrian Valdes Oct 03 '21 at 05:46
  • Yes, as expected your `getAllForms` is incorrect. `forEach` with`async / await` won't be doing what you expect. Like mentioned replace with `for of` this is compatible with `async / await`, what your seeing in the log is late evaluation from the console. IOW that bit were you click expand the promise would have completed, but at run time its still in progress. IOW:. `forEach` doesn't wait.. – Keith Oct 03 '21 at 09:59
  • Duplicate of [Using async/await with a forEach loop](https://stackoverflow.com/q/37576685/1048572) – Bergi Oct 03 '21 at 11:05

1 Answers1

0

I solved the problem... Was the forEach indeed, i only rewrite the data fetch, replacing the forEach with a for ... of:

await Promise.all(snapshot.docs.map(async doc => {  //Fetching in Paralel the data
        const docData = doc.data() as IForms
        const aux = [] as FormsData[];
        
        for (const id of docData.formsFieldId) {
            const test = await GetOneFormsField(id);
            aux.push(test);
        }

        const dataFormatted = { ...docData, formsFieldId: [...aux] }

        dataFormattedArray.push(dataFormatted);

    }))

thanks to everyone who reply to this! Cheers!