For people who are still trying to figure out how to implement async ejs templates, I am listing my complete solution below:
In your main app file (app.js)
// app.js
// Set ejs as view engine
app.set('view engine', 'ejs');
let ejsOptions = {
// delimiter: '?', Adding this to tell you do NOT use this like I've seen in other docs, does not work for Express 4
async: true
};
// The engine is using a callback method for async rendering
app.engine('ejs', async (path, data, cb) => {
try{
let html = await ejs.renderFile(path, data, ejsOptions);
cb(null, html);
}catch (e){
cb(e, '');
}
});
Now for your route responses...
app.route('/login')
.get( async (req, res) =>{
// layout.ejs is my version of blocking. I pass the page name as an option to render custom pages in the template
return await res.render(`layout.ejs`, { page : 'login' }, (err, html) => standardResponse(err, html, res));
})
I user the function standardResponse() in the callback for both readability and so I have to write less lines. The function works like this...
const standardResponse = (err, html, res) => {
// If error, return 500 page
if (err) {
console.log(err);
// Passing null to the error response to avoid infinite loops XP
return res.status(500).render(`layout.ejs`, { page : '500', error: err }, (err, html) => standardResponse(null, html, res));
// Otherwise return the html
} else {
return res.status(200).send(html);
}
}
And viola! Asynchronous ejs rendering.