Await in loop

Hey,
I want to update some entries of my database, but I don’t get how to wait in a loop until the onMessage has return and the database is updated.

Code:

export function button_click() {

    ArrayFromBackend().then((locations) => {

        locations.forEach(element => {

            console.log("Start ForEach");

            $w("#htmlAdresseUpdate").postMessage({ element });

            $w('#htmlAdresseUpdate').onMessage(() => {

                let toUpdate = {
                    //flieds to Update
                };
                wixData.update("Database", toUpdate);
                console.log("Database Update");
            });
            console.log("End ForEach");
        });
    });
}

Output:

Start ForEach
End ForEach
Database Update

How can I wait until the database is updated, before the loop continues?

I already searched for hours for a resolution, but they don’t work for my purpose or are way too complicated to understand.

Hi.
update() is asynchronous so try to await it.
https://www.wix.com/velo/reference/wix-data/update

change your function to async and add “await” before wixData.update().
Then the function will be waiting for resolving the Promise, that resolves when update is successful.

export async function button_click() {
    // your code
    console.log("Start ForEach");
    // your code
    await wixData.update("Database", toUpdate);
    console.log("Database Update");
    // your code
    console.log("End ForEach");
}

I think this may help.

Or another way.
To be sure that some code will run AFTER update(), you can use .then() instead of await. And put your code inside then()

export function button_click() {
    // your code
    console.log("Start ForEach");
    // your code
    wixData.update("Database", toUpdate)
    .then( () => {
        console.log("Database Update");
        // your code
        console.log("End ForEach");
    })
}

Hey,
it seems like await has no effect in a forEach Loop, I tried it with await, but the loop doesn’t pause.

I set a await for wixData.update:

ArrayFromBackend().then(async (locations) => {

        locations.forEach(element => {

            console.log("Start forEach");

            werte.push({ lat: element.lat, lng: element.lng });

            $w('#html').postMessage({ werte });

            $w('#html').onMessage(async (event) => {

                werte = [];

                let toUpdate = {
                    //update fields
                };
                await wixData.update("Database", toUpdate);
                console.log("Database Update");
            });
            console.log("Ende forEach");
        });
    });
}

//I import 2 entries from the backend ( ArrayFromBackend() )
Output:

Start ForEach
End ForEach
Start ForEach
End ForEach
Database Update
Database Update
Database Update
Database Update

When I await the postMessage, too:

 await $w('#html').onMessage(async (event) => {

Output:

Start ForEach
Start ForEach
End ForEach
End ForEach
Database Update
Database Update
Database Update
Database Update

Ooh… really, but okay, you can try cycle (for let i = 0) instead of forEach
I take jsonplaceholder.com for example of asynchronous request

async function foo () {
    console.log('before cycle')
    
    for (let i = 1; i < 5; i++) {
        console.log('before await')
        let response = await fetch(`https://jsonplaceholder.typicode.com/posts/${i}`);
        if (response.ok) await response.json()
        console.log(response);
        console.log('after await')
    }
    console.log('after cycle');
}
foo();

Output

before cycle

before await
Response {type: "cors", url: "https://jsonplaceholder.typicode.com/posts/1", redirected: false, status: 200, ok: true, …}
after await
before await
Response {type: "cors", url: "https://jsonplaceholder.typicode.com/posts/2", redirected: false, status: 200, ok: true, …}
after await
before await
Response {type: "cors", url: "https://jsonplaceholder.typicode.com/posts/3", redirected: false, status: 200, ok: true, …}
after await
before await
Response {type: "cors", url: "https://jsonplaceholder.typicode.com/posts/4", redirected: false, status: 200, ok: true, …}
after await

after cycle

It should work. Try this

Yeah, that fixed my problem thank you :smile:

Seems like it’s possible to await a value in a for loop, but not in the new forEach() function.