Home > Software design >  store foreach data and send after foreach
store foreach data and send after foreach

Time:05-18

let test = [];
myarray.forEach((obj) => {
  db.query('select * from table', (err, res) => {
    // can't use return res.send here bcoz its in foreach loop

    test.push(res);
  });
});

return res.send(test);

Output :
[ ]
"DATA"

Getting empty array at first but getting data the second time.

CodePudding user response:

This is because you're fetching data and not waiting for it.

This is how your code executes:

  1. Start foreach loop
  2. Start a request on each iteration
  3. Finish foreach loop
  4. Return array
  5. ...
  6. Your requests are completed down here, after the data is sent.

The goal is to loop through every item in your array, send the requests, wait for all responses, then continue to send your response. This is best achieved with promises & async/await. Read more here.

This is how i would resolve it.

async function runQueries() {
    // Configure array to store all promises
    const promises = []

    // Iterate through each item (this probably takes 0.001 seconds)
    myarray.forEach(obj => {
        // Run the query and store the ongoing request in the promises array
        promises.push(new Promise((resolve, reject) => {
            db.query('select * from table', (err, res) => {
                if (err) {
                    // If there was an error, send it to reject which will be caught in the try/catch
                    return reject(err)
                }

                // Return the success response
                resolve(res)
            })
        }))
    })

    // try/catch to handle any issues.
    try {
        // wait for all ongoing requests to finish and return either a response or error
        const result = await Promise.all(promises)

        // Return the result
        res.send(result)
    } catch (err) {
        console.log(err)
        
        // Send any error instead
        res.status(500).send(err)
    }
}

EDIT 1:

This is not tested, it's just to explain my approach to this type of issue.


EDIT 2:

Typo and wrapped in an async function

  • Related