Amir Gilboa Amir Gilboa - 6 months ago 47
Node.js Question

Warning: .then() only excepts functions

in mean stack / nodejs / mongoose app, i have this code:



User.findByIdAsync(req.params.id)
.then(handleEntityNotFound(res))
.then(saveUpdates(req.body))
.then(sendEmail()) // this is my addition
.then(respondWithoutResult(res))
.catch(handleError(res));





the function sendMail looks like this:



function sendEmail(body){
var mailOptions = {
from: 'Excited User <admin@blabla.com>',
to: 'johny@gmail.com',
subject: 'Hello',
text: 'body text here'
};

var smtpConfig = {
host: config.mailgun.smtp_host,
port: 465,
secure: true,
auth: {
user: config.mailgun.smtp_user,
pass: config.mailgun.smtp_pass
}
};


var transporter = nodemailer.createTransport(smtpConfig);
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);

});
}





when i run it, i get an error:
Warning: .then() only excepts functions but was passed: [object Undefined]

what should i change in sendEmail in order for it to work with .then() ?

Answer

Because sendMail supports promises, it can be as simple as this:

function sendEmail(body) {
  var mailOptions = {
    from: 'Excited User <admin@blabla.com>',
    to: 'johny@gmail.com',
    subject: 'Hello',
    text: 'body text here'
  };

  var smtpConfig = {
    host: config.mailgun.smtp_host,
    port: 465,
    secure: true,
    auth: {
      user: config.mailgun.smtp_user,
      pass: config.mailgun.smtp_pass
    }
  };

  var transporter = nodemailer.createTransport(smtpConfig);

  // Return the promise here.
  return transporter.sendMail(mailOptions);
}

If you want to maintain the logging, replace the last line with this:

return transporter.sendMail(mailOptions).then(function(info) {
  console.log('Message sent: ' + info.response);
  return info;
}, function(error) {
  console.log(error);
  throw error;
});

EDIT: I just noticed the body argument, which I'm guessing may be the result of saveUpdates(req.body)). If so, you need to restructure your promise chain a bit as well:

User.findByIdAsync(req.params.id)
    .then(handleEntityNotFound(res))
    .then(saveUpdates(req.body))
    .then(sendEmail)
    .then(respondWithoutResult(res))
    .catch(handleError(res));