0

I make a mailer with nodejs but i have some problems.

          var smtpSender;
      var smtpMailAdress;
      ipcMain.on("mail:send", (err, data) => {

      db.query("SELECT * FROM mail_accounts", (error, results, fields) => {
        var string=JSON.stringify(results);
        var json =  JSON.parse(string);
        smtpSender = nodemailer.createTransport({
              host: json[0].host,
              port: json[0].port,
              auth: {
                user: json[0].username,
                pass: json[0].password  
              }
          });
          smtpMailAdress = json[0].username
        });
        console.log(smtpSender);
        console.log(smtpMailAdress);
  });

smtpSender and smtpMailAdress is not updated it still undefined. How can i figure it.Thanks.

  • Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – VLAZ Mar 19 '22 at 10:10
  • I'm new at nodejs i dont understand it can you help me. – Yasin Kara Mar 19 '22 at 10:21

2 Answers2

1

db.query is asynchronous which means that when it is triggered, the runtime keeps going forward, while its callback function gets executed when the database sends back the results.

Here is what happens for the runtime executor:

  1. triggers db.query
  2. logs smtpSender -> undefined
  3. logs smtpMailAdress -> undefined
  4. executes db.query's callback which modifies the content of smtpSender and smtpMailAdress

If you move the console.logs in the callback, it will work. However, it is probably not what you want, because you may not want to move your entire code inside the callback.

A simple way to handle this is to promisify your call to the database and await its completion:

var smtpSender;
var smtpMailAdress;
ipcMain.on('mail:send', async (err, data) => {
  await new Promise((resolve) => {
    db.query('SELECT * FROM mail_accounts', (error, results, fields) => {
      var string = JSON.stringify(results);
      var json = JSON.parse(string);
      smtpSender = nodemailer.createTransport({
        host: json[0].host,
        port: json[0].port,
        auth: {
          user: json[0].username,
          pass: json[0].password,
        },
      });
      smtpMailAdress = json[0].username;
      resolve();
    });
  });
  console.log(smtpSender);
  console.log(smtpMailAdress);
});

Ben
  • 1,331
  • 2
  • 8
  • 15
  • you're welcome, you should validate the answer then :) – Ben Mar 19 '22 at 10:40
  • Making a DB request awaiting just for 2 console.log is a very very bad idea as this make the process synchronous where the advantage of using node.js is asynchronous. – Alaindeseine Mar 19 '22 at 10:40
  • @Alaindeseine, I'm guessing that he wants to do more with those variables than just logging them... And I pointed out that placing the console.log in the callback would work. But note that using async/await does not block the NodeJS executor so it does not change anything to the advantage of node asynchronicity – Ben Mar 19 '22 at 10:44
  • You misRead what i wrote, I never wrote that await block the executor. – Alaindeseine Mar 19 '22 at 10:47
  • I'm afraid you are mistaken in your understanding of NodeJS asynchronicity. Awaiting a promise has no impact on the execution as it does not block the runtime executor – Ben Mar 19 '22 at 10:52
0

This solution is better if you want just pint to the console your vars:

      var smtpSender;
  var smtpMailAdress;
  ipcMain.on("mail:send", (err, data) => {

  db.query("SELECT * FROM mail_accounts", (error, results, fields) => {
    var string=JSON.stringify(results);
    var json =  JSON.parse(string);
    smtpSender = nodemailer.createTransport({
          host: json[0].host,
          port: json[0].port,
          auth: {
            user: json[0].username,
            pass: json[0].password  
          }
      });
      smtpMailAdress = json[0].username
      console.log(smtpSender);
      console.log(smtpMailAdress);
    });

});

By doing like this, you don't break asynchronous execution provide by node.js, is better for performance and for server health.

Alaindeseine
  • 3,260
  • 1
  • 11
  • 21