如何在该控制器功能中包括该nodemailer功能? [英] How to include this nodemailer function inside this controller function?

查看:74
本文介绍了如何在该控制器功能中包括该nodemailer功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个表单,该表单首先将数据发送到Mongo数据库,然后再通过Nodemailer的电子邮件发送该数据.这是2个功能:

I am trying to create a form that will send data to the Mongo DB first then will send that data through the email by Nodemailer. Here are the 2 functions:

控制器功能

exports.createListing = (req, res) => {
    // Validate request
    if(!req.body.content) {
        return res.status(400).send({
            message: "Fields can not be empty"
        });
    }

    const listing = new Listing({
        title: req.body.title, 
        city: req.body.city,
        street: req.body.street,
        businessname: req.body.businessname,
        description: req.body.description
    });

    listing.save()
    .then(data => {
        res.send(data);
    }).catch(err => {
        res.status(500).send({
            message: err.message || "Some error occurred while creating the listing."
        });
    });
};

NodeMailer功能

 var smtpTransport = nodemailer.createTransport({
        service: 'Gmail',
        port: 465,
        auth: {
          user: 'YOUR_GMAIL_SERVER',
          pass: 'YOUR_GMAIL_PASSWORD'
        }
      });

      var mailOptions = {
        to: data.email,
        subject: 'ENTER_YOUR_SUBJECT',
        html: `<p>${data.title}</p>
              <p>${data.city}</p>
              <p>${data.street}</p>`,
              ...
      };

      smtpTransport.sendMail(mailOptions,
        (error, response) => {
          if (error) {
            res.send(error)
          } else {
            res.send('Success')
          }
          smtpTransport.close();
        });

如何在上面的创建列表功能中包含此Nodemailer部分,以及如何在电子邮件正文中包含已提交的数据.我认为电子邮件正文中的当前data.title和其他选项是错误的方式.

How can I include this Nodemailer part inside the above create listing function also how can I include that submited data inside email body. I assume current data.title and other options inside email body are wrong way.

推荐答案

这里最简单的形式是将函数与回调(nodemailer one)一起包装在Promise中:

The most simple form here would be to just wrap the function with the callback ( the nodemailer one ) in a Promise:

exports.createListing = (req, res) => {
    // Validate request
    if(!req.body.content) {
        return res.status(400).send({
            message: "Fields can not be empty"
        });
    }

    // Set options after the request was verified.

    const smtpTransport = nodemailer.createTransport({
        service: 'Gmail',
        port: 465,
        auth: {
          user: 'YOUR_GMAIL_SERVER',
          pass: 'YOUR_GMAIL_PASSWORD'
        }
    });

    const listing = new Listing({
        title: req.body.title, 
        city: req.body.city,
        street: req.body.street,
        businessname: req.body.businessname,
        description: req.body.description
    });

    listing.save()
    .then(data => new Promise((resolve, reject) => {
      var mailOptions = {
        to: data.email,
        subject: 'ENTER_YOUR_SUBJECT',
        html: `<p>${data.title}</p>
              <p>${data.city}</p>
              <p>${data.street}</p>`,
              ...
      };

      smtpTransport.sendMail(mailOptions,
        (error, response) => {
          if (error) {
            reject(error);
          } else {
            resolve(data);
          }

        });

    })
    .then(data => {
      smtpTransport.close(); // this awaited the actual send
      res.send(data); 
    }
    .catch(err => {
        res.status(500).send({
            message: err.message || "Some error occurred while creating the listing."
        });
    });
};

请注意,此处的resolve(data)有效地将结果传递到Promise链中的下一个链接,这比在相同范围内嵌套promise链更好,因为只可以访问相同的值.然后,当这两个方法中的任何一个失败时,您都具有catch()的单点.

Note that the resolve(data) here is effectively passing through the result to the next link in the Promise chain, which is better than nesting promise chains in the same scope just to have access to the same value. Then you also have the single point for catch() when either of methods fail.

也就是说,已经引起注意的是,当前的API在没有回调的情况下调用时实际上会返回Promise,但是您可能希望使用asyncawait语法以使对内容的访问更干净:

That said, it has been brought to attention the current API actually would return a Promise when invoked without a callback, but then you would probably want async and await syntax in order to make access to things cleaner:

exports.createListing = async (req, res) => { // <-- mark block as async
    // Validate request
    if(!req.body.content) {
        return res.status(400).send({
            message: "Fields can not be empty"
        });
    }

    // Set options after the request was verified.

    const smtpTransport = nodemailer.createTransport({
        service: 'Gmail',
        port: 465,
        auth: {
          user: 'YOUR_GMAIL_SERVER',
          pass: 'YOUR_GMAIL_PASSWORD'
        }
    });

    const listing = new Listing({
        title: req.body.title, 
        city: req.body.city,
        street: req.body.street,
        businessname: req.body.businessname,
        description: req.body.description
    });

    try {                                    // try..catch for error handling

      let data = await listing.save();       // await the save

      var mailOptions = {
        to: data.email,
        subject: 'ENTER_YOUR_SUBJECT',
        html: `<p>${data.title}</p>
              <p>${data.city}</p>
              <p>${data.street}</p>`,
              ...
      };

      await smtpTransport.sendMail(mailOptions);   // await the sendMail

      smtpTransport.close(); // this awaited the actual send
      res.send(data); 
    } catch(err) {
      res.status(500).send({
         essage: err.message || "Some error occurred while creating the listing."
    }
};

同样重要的是要注意,这种方法在执行中是 serial .因此,除非正确保存数据,否则不会发送邮件.这可能是您的预期情况,也可能不是您的预期情况,但仅创建包装的Promise至少应遵循正确的方向.

It is also important to note that this approach is serial in execution. So here the mail is not sent unless the data is correctly saved. This may or may not be your intended case, but simply creating the wrapping Promise should at least the right direction to follow.

这篇关于如何在该控制器功能中包括该nodemailer功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆