4

I've written a node js module that sends emails. The module is a wrapper for the nodemailer module. When the callback of transporter.sendMail is executed, I want my wrapper function to return true if the email was sent, or false otherwise. How can I do this? Here's the code:

var nodemailer = require('nodemailer');

module.exports.sendEmail = function (mailerAddress, mailerPassword, to, subject, html) {
var transporter, mailOptions;

transporter = nodemailer.createTransport({
    service: 'Gmail',
    auth: {
        user: mailerAddress,
        pass: mailerPassword
    }
}); 

mailOptions = {
    from: mailerAddress, 
    to: to,
    subject: subject,
    html: html
};

transporter.sendMail(mailOptions, function(error, info) {
    if (error) {
        return false;
    }
    else {
        return true;
    }
});         
};
Mister_L
  • 2,469
  • 6
  • 30
  • 64

3 Answers3

3

If I understood, the "wrapper function" that you're saying is the callback function, so if I I'm correct, try to do something like this:

var EmailUtil = {
    sendEmail : function sendEmail(mailerAddress, mailerPassword, to, subject, html, callback) {
        var options = {
            service: 'Gmail',
            auth: {
                user: mailerAddress,
                pass: mailerPassword
            }
        };
        var transport = nodemailer.createTransport(options);

        transport.sendMail({
            from: mailerAddress, 
            to: to,
            subject: subject,
            html: html
        }, function(err, responseStatus) {
            var val;
            if (error) {
                val = false;
            } else {
                val = true;
            }
            callback(error, val);
        });
    }
};

module.exports = EmailUtil;

This is a real example that I use in production.

danilodeveloper
  • 3,840
  • 2
  • 36
  • 56
  • Why do put this way `sendEmail : function sendEmail`? – Jonatas Walker Nov 17 '15 at 15:23
  • @JonatasWalker this is a very long answer... in short: **1 -** I like to group functions by responsability, for example `EmailUtil` and `EmailOperations`, so inside `EmailUtil` I can create functions like `isEmailValid(...)`, `checkEmailLenght(...)` and inside `EmailOperations` I can create functions like `sendEmail(...)`, `deleteEmail(...)`. **2 -** Write less `module.exports` declarations because the groupings. **3 -** Separation of Concerns. **4 -** And a bit of personal preference :) Of course, we can do this in many ways, your answer is an example of another way to do that. Cheers! – danilodeveloper Nov 17 '15 at 17:02
3

You could also make use of Promises:

Module

module.exports.sendMail = function(mailOptions) {
  var transporter = ....;
  return new Promise(function(resolve, reject) {
    transporter.sendMail(mailOptions, function(error, info) {
      if (error) {
        reject(error);
      } else {
        resolve(info);
      }
    });
  });
};

App

var module = require('...');
var mail = {
  to: '...',
  from: '...'
};
module.sendMail(mail).then(function(response) {
  console.info(response);
}).catch(function(error) {
  console.info(error);
});
Jonatas Walker
  • 13,583
  • 5
  • 53
  • 82
2

I'd argue you shouldn't be doing that, because you're effectively trying to turn an async operation into a sync one. If you're intent on this then I'd suggest looking at this answer, which uses async.

Simplest way to wait some asynchronous tasks complete, in Javascript?

Community
  • 1
  • 1
Chris Kemp
  • 2,069
  • 2
  • 18
  • 27
  • Here is an excellent reference to callbacks, promises and Async/ Await: [Async/Await in JavaScript (Youtube) by CodeWorkr, Published on Aug 22, 2017](https://www.youtube.com/watch?v=f57IHEeDNcA) . Repo for video is [here](https://github.com/eXtremeXR/Async-Await) – zipzit Jan 07 '18 at 09:59