It’s often handy to be able to display a notification to users, noting a successful operation for example, or showing errors.
With Express this is normally done using a “flash message”. You’ll need the connect-flash middleware, as it was unbundled in Express 3.
var express = require('express'),
flash = require('connect-flash'),
app = express();
app.use(flash());
app.use(function(req, res, next){
res.locals.success = req.flash('success');
res.locals.errors = req.flash('error');
next();
});
The 2nd piece of middleware ensures that flash messages will be available to the template as locals.
router.get('/account/name', function (req, res) {
var data = {
firstName: req.user.firstName,
lastName: req.user.lastName
};
res.render('settings_name', data);
});
router.post('/account/name', function (req, res) {
req.user.updateName(req.user.id, req.body.firstName, req.body.lastName, function(err) {
if (err) {
req.flash('error', 'Could not update your name, please contact our support team');
} else {
req.flash('success', 'Your name was updated');
}
res.redirect('/account/name');
});
});
The final step is to display the messages when necessary. Bootstrap alerts provide an easy way to do this:
doctype html
html
head
link(rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css")
body
if error && error.length > 0
.alert.alert-danger.alert-dismissible.fade-in(role="alert")
button.close(type="button" data-dismiss="alert" aria-label="Close")
span(aria-hidden="true") ×
p= error
if success && success.length > 0
.alert.alert-success.alert-dismissible.fade-in(role="alert")
button.close(type="button" data-dismiss="alert" aria-label="Close")
span(aria-hidden="true") ×
p= success
script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js")
script(src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js")
I’ve been doing it this way (as described in the article) for quite some time, and I discovered that the flash messages are lost on redirect. So instead of this:
app.use(function(req, res, next){
res.locals.success = req.flash(‘success’);
res.locals.errors = req.flash(‘error’);
next();
});
I now do this:
// middleware for all views
app.use((req, res, next) => {
// Pass the flash prototype; the templates will use it to get the messages
// (this works with redirect)
res.locals.flash = req.flash;
next();
});
Then in my views (I use EJS templating), wherever I want to show the flash messages, I include a ‘partial’ that looks like this:
(. . . continues . . .)
Hmm. It’s not allowing me to post the contents of the EJS.