Search code examples
javascriptnode.jsreactjsnodemailer

how to Send html email with dynamic value?


const doc = [{id: 2, title: 'hello word', email: 'test@email.com'},{id: 3, title: 'post data'}, email: 'test@email.com'}]

 {
                    doc.map(data => {
                        var readHTMLFile = function (path, callback) {
                            fs.readFile(path, { encoding: 'utf-8' }, function (err, html) {
                                if (err) {
                                    throw err;
                                    callback(err);
                                }
                                else {
                                    callback(null, html);
                                }
                            });
                        };

                        readHTMLFile(__dirname + '/../emailTemplates/newsletter.html', function (err, html) {
                            var template = handlebars.compile(html);
                            var replacements = {
                                name: data.name
                            };
                            var htmlToSend = template(replacements);
                            var mailOptions = {
                                from: 'info@fnmotivation.com',
                                to: data.email,
                                subject: 'Check out story posts in your communities',
                                html: htmlToSend
                            };
                            transporter.sendMail(mailOptions, function (err, info) {
                                if (err) {
                                    console.log(err);
                                    callback(err);
                                }
                            });
                        });
                    })
                }

I want to mail only once the data stored in doc variable but the mail is sent twice probably because I used map the doc variable. Any Idea how to send in one mail?


Solution

  • Remove doc.map method and get toEmailAddresses as comma separated string from the doc list.

    const doc = [{ id: 2, title: 'hello word', email: 'test@email.com' }, { id: 3, title: 'post data', email: 'test@email.com' }]
    
    const readHTMLFile = function (path, callback) {
      fs.readFile(path, { encoding: 'utf-8' }, function (err, html) {
        if (err) {
          throw err;
          callback(err);
        }
        else {
          callback(null, html);
        }
      });
    };
    
    readHTMLFile(__dirname + '/../emailTemplates/newsletter.html', function (err, html) {
      const template = handlebars.compile(html);
      const toEmailAddresses = doc.map(data => data.email).join(); // to get email addresses.
    
      const mailOptions = {
        from: 'info@fnmotivation.com',
        to: toEmailAddresses,
        subject: 'Check out story posts in your communities',
        html: template
      };
      transporter.sendMail(mailOptions, function (err, info) {
        if (err) {
          console.log(err);
          callback(err);
        }
      });
    });