skip to Main Content

I am used to java and I recently started a project in NodeJS and I encountered some problems with the logic behind NodeJS I think.
I have this function that needs to execute a query multiple times (changing the parameters at every iteration) and store the result in an array.

I created an array variable let FINAL = [] and i am trying to push in data when the data is retrieved per iteration.

const fluxAccesParPeriode = async (req, res) => {
    try {
        const db = res.locals.db;
        const {date_debut, date_fin} = req.body;

        if (!date_debut || !date_fin) {
            res.status(400).json({error: 'One or more informations are missing.'});
            return;
        }

        // SQL
        const queryText = "SELECT COUNT(id_pointage) AS nbreAcces FROM pointage_adherents PA, adherents A WHERE PA.id_adherent=A.id_adherent AND date BETWEEN ? AND ? AND heure_entree BETWEEN ? AND ?";

        let FINAL = [];

        for (let i = 0; i < 24; i += 3) {
            let heure_debut = i + ":00:00";
            let heure_fin = (i + 3) + ":00:00";

            await db.execute(queryText,
                [date_debut, date_fin, heure_debut, heure_fin],
                (err, results) => {
                    if (err) {
                        console.error('Error executing SQL query:', err);
                        res.status(500).json({error: 'Internal Server Error'});
                        return;
                    }

                    console.log(heure_debut + "  /   " + heure_fin + "  /  " + results[0]["nbreAcces"]);

                    FINAL.push({heure_debut: heure_debut, heure_fin: heure_fin, result: results[0]["nbreAcces"]});
                });
        }

        console.log("RESULT : " + FINAL);

        if (FINAL.length > 0) {
            res.status(200).json(FINAL);
        } else {
            res.status(400).json({error: 'Error while executing your query: fluxAccesParPeriode'});
        }

    } catch (error) {
        console.error(error.stack);
        res.status(500).json({message: 'Erreur lors de l'exécution de la requête'});
    }
}

What i noticed is that the last console.log is printed first before the console.log inside the loop. I tried to add await but still the same issue.

Here is an image of what I am getting in the terminal:

enter image description here

What am I missing ?

2

Answers


  1. This is how node js event loop works. For loop will run and put all the db query in a queue and surpass the loop and print the last "RESULT" log.

    Then whatever query is resolved and get the response from DB, that particular query will print the log. thats why you have random sequence.

    Best Solution for this will be to use promise all method something like:

    const fluxAccesParPeriode = async (req, res) => {
        try {
            const db = res.locals.db;
            const { date_debut, date_fin } = req.body;
    
            if (!date_debut || !date_fin) {
                res.status(400).json({ error: 'One or more informations are missing.' });
                return;
            }
    
            // SQL
            const queryText = "SELECT COUNT(id_pointage) AS nbreAcces FROM pointage_adherents PA, adherents A WHERE PA.id_adherent=A.id_adherent AND date BETWEEN ? AND ? AND heure_entree BETWEEN ? AND ?";
            let FINAL = [];
    
            for (let i = 0; i < 24; i += 3) {
                let heure_debut = i + ":00:00";
                let heure_fin = (i + 3) + ":00:00";
                FINAL.push(db.execute(queryText, [date_debut, date_fin, heure_debut, heure_fin]));
            }
    
            const results = await Promise.all(FINAL);
    
            results.forEach(element => {
                console.log(heure_debut + "  /   " + heure_fin + "  /  " + results[0]["nbreAcces"]);
            });
            console.log("RESULT : " + results);
    
             res.status(200).json(results);
    
        } catch (error) {
            console.error(error.stack);
            res.status(500).json({ message: 'Erreur lors de l'exécution de la requête' });
        }
    }
    Login or Signup to reply.
  2. Your call to await db.execute(query,variable,callback) looks like it is using the callback paradigm instead of promises, so the await doesn’t do anything since the call to db.execute isn’t returning a promise.

    I’m not sure if promisify promisify will work, since it probably needs the binding to db, but it is easy to promisify the call on the fly.

    Since you have the for-loop inside a try/catch block I remove the exit from inside the lopp to throwing an exception with reject.

    for (let i = 0; i < 24; i += 3) {
      let heure_debut = i + ':00:00';
      let heure_fin = i + 3 + ':00:00';
      const results = await new Promise((resolve, reject) => {
        db.execute(queryText, [date_debut, date_fin, heure_debut, heure_fin], (err, results) =>
          err ? reject(err) : resolve(results)
        );
      });
    
      console.log(heure_debut + '  /   ' + heure_fin + '  /  ' + results[0]['nbreAcces']);
    
      FINAL.push({ heure_debut: heure_debut, heure_fin: heure_fin, result: results[0]['nbreAcces'] });
    }
    

    A suggestion: You can probably rewrite the SQL query to let the database do the grouping. That will improve performance and only requires one call to the database.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search