getmicah getmicah - 2 months ago 6x
Node.js Question

Why can't I use a if statement inside of my express handlebars template?

I've recently began working on my first Express project and I chose to use Handlebars as my template language because I had some prior experience when creating Ghost blog themes.

I'm creating a login screen using Passport.js and connect-flash to send error messages to the user. I'm able to pass in the error messages as a handlebars helper just fine but when I attempt to include an if statement inside the handlebars template it is always false even when there is an error message.

Here's my code:

login.js (route)

.get(function(req, res) {
if (req.isAuthenticated()) {
} else {
res.render('login', {
helpers: {
message: req.flash('loginMessage')


<form action="/login" method="post">
<input type="text" name="email">
<input type="password" name="password">
<button type="submit">Log In</button>

{{#if message}}
<p style="color: red">{{message}}</p>

This works without the if statement:

<p style="color: red">{{message}}</p>

But I don't like the idea of having empty elements all over my html. Any help would be greatly appreciated as I'm sure I'm missing something very simple.



I believe you must use a subexpression in order to invoke multiple helpers within a single mustache. The fix is as simple as adding parentheses:

{{#if (message)}}
    <p style="color: red">{{message}}</p>


Note that the above assumes that the type of object at helpers.message is a function as the Handlebars documentation states that helpers are functions. However, the connect-flash documentation suggests that req.flash('loginMessage') will return an array. In this case, the result should not be assigned to a helper, but should be a regular value of the view model object:

res.render('login', {
    messages: req.flash('loginMessage')

Within our template, as messages is an array, we will have to lookup and access its 0th element:

{{#if (lookup messages 0)}}
    <p style="color: red">{{messages.[0]}}</p>