Home > Software engineering >  Event listener for foreach loop completion
Event listener for foreach loop completion

Time:10-15

so what I have right now is

window.addEventListener('load', fetchInfo)

function fetchInfo() {
    const tableRows = //an array of results

    tableRows.forEach((row) => {
        const rowId = //get the id of each row
        fetch(...) //fetch some stuff using the id
            .then(() => {
                //do some stuff
                return rowId;
            })
            .then((id) => {
                //do some stuff
                }
            })
    })
}

basically using rowId to fetch information and populate each table row, so this happens a few times, the table maxes out at 10 rows so max 10 fetches

I want to have an event listener to see when all the fetching is done, aka when the table is completely done loading. How should I go about that?

Edit: these fetches are api requests so they take a few seconds to respond. I've tried using Promise.all(tableRows.map(row) => and it returned results before the api could respond. So in the end, it still doesn't really detect when does the table actually finish loading information.

CodePudding user response:

First try to map your rows (not foreach) to Promises of results:

const tableResultPromises = tableRows.map((row)=>...)

Then await for them all with Promise.all:

const tableResult = await Promise.all(tableResultPromises)

If you don't like async...await syntax, you can still use Promise.all.then.

CodePudding user response:

Use Promise.all:

async function fetchInfo() {
    const tableRows = //an array of results
    const results = await Promise.all(tableRows.map(row => fetch(...))
    console.log(results)
}

CodePudding user response:

From the suggestion in the comments length was indeed the way, however that would only be half of the solution. Because the key point here is that I want to know whether or not the table has been fully populated with requested information.

Tried Promise.all and map() and didn't work out because as stated in my edit, these will return when the fetch was called, when the fetch was still pending, and doesn't really care if the fetch was a 200 OK, which was what I needed.

So the solution was to use response.status

function fetchInfo() {
    const tableRows = ...
    let successFetch = 0;

    tableRows.forEach((row) => {
        fetch(...)
            .then((response) => {
                if (response.status == 200) {
                    successFetch = successFetch   1
                }
                if (successFetch == tableRows.length) {
                    //this point here was exactly what I needed
                }
                return response;
            })
            .then((response) => {
                ...
            })
    })
}

CodePudding user response:

Use Promise.all to wait for all promises to complete

Promise.all(
    tableRows.map((row) => {
        return fetch(...).then(() => {
            return rowId;
        })
    })
).then((results) => {
    console.log(results);
})
  • Related