Reputation: 412
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)
app.route('/login')
.get(function(req, res) {
if (req.isAuthenticated()) {
res.redirect('/');
} else {
res.render('login', {
helpers: {
message: req.flash('loginMessage')
}
});
}
})
.post(...);
login.handlebars
<form action="/login" method="post">
<div>
<label>Email</label>
<input type="text" name="email">
</div>
<div>
<label>Password</label>
<input type="password" name="password">
</div>
<button type="submit">Log In</button>
</form>
{{#if message}}
<p style="color: red">{{message}}</p>
{{/if}}
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.
Thanks.
Upvotes: 0
Views: 1908
Reputation: 29
This is probably coming way toooooo late, but for those who will still encounter this or related problem in the future, I hope this works for you.
Another way you could do it is to use res.redirect('/login');
instead of res.render('login)
.
Add this to your SERVER/INDEX.JS
const flash = require('connect-flash');//import this guy
app.use(flash());
app.use(function(req, res, next) {
res.locals.message = req.flash('loginMessage');
next();
});
Your LOGIN.JS will look like this
app.route('/login')
.get(function(req, res) {
if (req.isAuthenticated()) {
res.redirect('/');
return;//you should always return if there's no more thing to do
} else {
req.flash('loginMessage', 'your message here');
res.redirect('/login');
return;//you should always return if there's no more thing to do
};
})
.post(...);
The above approach makes it easier for you to reuse your messages. Eg., You can reuse the above message by just changing req.flash('loginMessage', 'your message here');
to this req.flash('loginMessage', 'another message here');
.
You can also reuse the entire message by moving all error and success messages inside a PARTIAL folder and then using it in all your other pages in your front-end by inserting this {{>yourMessages}}
in all the pages.
your LOGIN.handlebars
<form action="/login" method="post">
<div>
<label>Email</label>
<input type="text" name="email">
</div>
<div>
<label>Password</label>
<input type="password" name="password">
</div>
<button type="submit">Log In</button>
</form>
{{#if message}}
<p style="color: red">{{message}}</p>
{{/if}}
Upvotes: 0
Reputation: 9003
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>
{{/if}}
Edit
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>
{{/if}}
Upvotes: 1