Reputation: 75
I am trying to send email through an HTML template that resides in the same path under a folder named 'view'. The HTML template name is 'index.handlebars'. But it is giving some weird error of path, though I think the path is absolutely proper. Can anyone please help me to fix this issue?
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined at validateString (internal/validators.js:125:11) at Object.resolve (path.js:161:7) at ExpressHandlebars._resolveLayoutPath (E:\NODE JS EXAMPLES\node-practice-one\node_modules\express-handlebars\lib\express-handlebars.js:342:17) at ExpressHandlebars. (E:\NODE JS EXAMPLES\node-practice-one\node_modules\express-handlebars\lib\express-handlebars.js:223:35)
const express = require('express');
const path = require('path');
const nodemailer = require('nodemailer');
const hbs = require('nodemailer-handlebars');
const log = console.log;
// Step 1
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL || '[email protected]', // TODO: your gmail account
pass: process.env.PASSWORD || 'abcd' // TODO: your gmail password
}
});
router.post('/send_mail', (req, res, next) => {
// Step 2
transporter.use(
'compile',
hbs({
viewEngine: 'express-handlebars',
viewPath: './views/'
})
);
// Step 3
let mailOptions = {
from: '[email protected]', // TODO: email sender
to: '[email protected]', // TODO: email receiver
subject: 'Nodemailer - Test',
text: 'Wooohooo it works!!',
template: 'index',
context: {
name: 'test user'
} // send extra values to template
};
// Step 4
transporter.sendMail(mailOptions, (err, data) => {
console.log(err);
if (err) {
return log('Error occurs');
}
return log('Email sent!!!');
});
});
Please suggest to me, what should I do to fix the error.
Upvotes: 0
Views: 3484
Reputation: 49729
inside hbs options you did not mention layoutsDir which contains layout.hbs
layout.hbs holds the default HTML skeleton and this is the file which will be extended by all the other view files. By default files in “views” folder will use this basic skeleton and then render their specific content in this {{{body}}} part. this is the hook where other views will come in and render their content.
hbs({
defaultLayout: "layout",
extname: ".hbs",
layoutsDir: __dirname + "/views/layouts",
partialsDir: __dirname + "/views/partials"})
then inside views folder create layouts folder and partials folder. create layout.hbs inside layouts directory. inside this file insert a basic html skeleton and inside the body, place this
{{{body}}}
Upvotes: 1