Send response after email send node express
LATEST EDIT In the comments you mention it is middleware, which would be correct with the function signature of (req, res, next).
But when I look at the line you posted in the comments router.post("/user/signup",UserController.signup);
it is a normal route where the signature should be (req, res).
So could you try:
const {sendEmail} = require("../lib/email");
exports.signup = async (req, res) => {
try {
//validate request and save user in DB
let content = {
activateLink: "link to activate email",
};
const result = await sendEmail(email, "Verification OTP", "otp", content);
res.status(201).json({
message: "User created successfully !",
userData: {
_id: result._id.toString(),
email: result.email,
},
});
}
catch (err) {
console.log(`Something went wrong sending activation mail`, err);
throw new Error(err);
}
};
import { rejects } from "assert";
exports.sendEmail = async (to, subject, viewName, content) => {
return new Promise((resolve, reject) => {
const transporter = nodemailer.createTransport(config.mailConfig);
const handlebarsOptions = {
viewEngine: {
extName: ".handlebars",
layoutsDir: viewPath,
defaultLayout: false,
partialsDir: partialsPath,
},
viewPath: viewPath,
extName: ".handlebars",
};
transporter.use("compile", hbs(handlebarsOptions));
const mailOptions = {
from: "[email protected]", // Update from email
to: to,
subject: subject,
template: viewName,
context: content,
};
let info = transporter.sendMail(mailOptions, (err, result) => {
if (err) {
reject(err);
return;
}
console.log("Message sent: %s", result.messageId);
resolve(result);
});
});
};
Which version of nodemailer are you using? Pre 6.4.1 does not return a Promise so you need to use a callback then.
With callback the code will look something like this:
const {sendEmail} = require("../lib/email");
exports.signup = async (req, res, next) => {
try {
//validate request and save user in DB
let content = {
activateLink: "link to activate email",
};
const result = await sendEmail(email, "Verification OTP", "otp", content, next);
res.status(201).json({
message: "User created successfully !",
userData: {
_id: result._id.toString(),
email: result.email,
},
});
}
catch (err) {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
}
};
import { rejects } from "assert";
exports.sendEmail = async (to, subject, viewName, content) => {
return new Promise((resolve, reject) => {
const transporter = nodemailer.createTransport(config.mailConfig);
const handlebarsOptions = {
viewEngine: {
extName: ".handlebars",
layoutsDir: viewPath,
defaultLayout: false,
partialsDir: partialsPath,
},
viewPath: viewPath,
extName: ".handlebars",
};
transporter.use("compile", hbs(handlebarsOptions));
const mailOptions = {
from: "[email protected]", // Update from email
to: to,
subject: subject,
template: viewName,
context: content,
};
let info = transporter.sendMail(mailOptions, (err, result) => {
if (err) {
reject(err);
return;
}
console.log("Message sent: %s", result.messageId);
resolve(result);
});
});
};
And you need to return the result (info) from let info = await transporter.sendMail(mailOptions);
to the signup
method.
_id: result._id.toString(), <-- result will be undefined here
email: result.email, <-- result will be undefined here