I'm trying to use handlebars
with nodemailer
in order to create a template for emails. Also, I'm trying to get the data from my mongodb database to be able to be displayed on this template. Nodemailer
is working perfectly fine, but I've never used handlebars
before, and I keep getting an error saying failed to lookup view \"orders\" in views directory
. If anyone knows why this could be happening, I would really appreciate any help or guidance on how to fix this. Thank you!
mailer.js
import express from 'express';
import expressAsyncHandler from 'express-async-handler';
import nodemailer from 'nodemailer';
import hbs from 'nodemailer-express-handlebars';
import Order from './models/orderModel.js';
const mailerRouter = express.Router();
mailerRouter.post (
'/order',
expressAsyncHandler(async (req, res) => {
const email = req.body.email
const orderId = req.body.orderId
const em = req.body.em
const sender = req.body.sender
const emailBody = await Order.findById(orderId).exec((err, orderData) => {
if (orderData) {
res.render('orders', {data:orderData})
}
})
const sub = `Order: ${orderId}`
let transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
service: 'gmail',
auth: {
type: 'OAuth2',
user: sender,
pass: '',
clientId: '',
clientSecret: '',
refreshToken: '',
}
})
transporter.use('compile', hbs({
viewEngine: 'express-handlebars',
viewPath:'./views/'
}))
const mailOptions = {
from: sender,
to: em,
subject: sub,
text: "Hello world?", // plain text body
template: 'orders',
}
console.log(mailOptions.subject)
transporter.sendMail(mailOptions, function (err, info) {
if(err)
console.log(err)
else
console.log(info);
});
}))
export default mailerRouter;
server.js
import express from 'express';
import cors from 'cors';
import mongoose from 'mongoose';
import dotenv from 'dotenv';
import path from 'path';
import hbs from 'express-handlebars';
import returnRouter from './routers/returnRouter.js';
import mailerRouter from './mailer.js';
dotenv.config();
const app = express();
app.use(cors()); //and thisnp
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
mongoose.connect(process.env.MONGODB_URL || 'mongodb://localhost/AM', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
});
app.use('/api/orders', orderRouter);
app.use('/api/mailer', mailerRouter);
app.get('/', (req, res) => {
res.send('Server is ready');
});
app.engine('hbs', hbs({
defaultLayout: 'template',
extname: '.hbs',
}));
app.set('views', __dirname + '/views');
app.set('view engine', 'hbs');
app.use((err, req, res, next) => {
res.status(500).send({ message: err.message });
});
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`Serve at http://localhost:${port}`);
});
orders.hbs (within a views folder)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
</style>
</head>
<body>
{{#each data.orderItems}}
<div>
<h1>{{name}}</h1>
</div>
{{/each}}
</body>
</html>
Directory
- backend
|-- modeles
| | -- orderModel.js
| | -- ... other files
|
|
|-- routes
| | -- orderRoutes.js
| | -- ... other files
|
|
|-- views
| | -- orders.hbs
|
| -- server.js
| -- mailer.js
| -- utils.js
| ... other files
- frontend
| -- other directories