Display Node.js Flash Messages using EJS
In this tutorial, we are going to learn how to use connect-flash to display server operation messages with EJS. We will use express-sessions and cookies-parser alongside the connect-flash package to deliver the messages to the views.
Connect-flash is used for passing messages between pages to display server operations such as success or errors messages. An example would be a registration form. Once the registration form is submitted you might want to display a ‘success’ or ‘error’ message to the user.
In this example, we will create a very simple page with a form where the user can enter their name and submit. On form submission, we can then display the user’s name and a success message.
Let’s start by creating a new application with Node.js.
To do that, create a new project folder and then run the following command in Command Line (Mac / Linux) or Powershell (Windows).
npm init
This will initialise a new project for you and it’s going to ask you a few questions about your project. The most important one is to give your package a name and then you can just keep pressing enter until the installation is over.
You can skip all questions by adding the “-y” flag like in the example below:
npm init -y
At this point, you should see a file called package.json in your project folder.
Dependencies Installation
We have to install a few dependencies (unfortunately too many, if you ask me):
[x] express [x] express-session [x] cookie-parser [x] connect-flash [x] ejs
Open the Command Line / Terminal / Powershell and install the dependencies listed above just like so:
npm install express express-session cookie-parser connect-flash ejs
Your packages.json file should look similar to this:
{ "name": "Nodejs-EJS-Flash-Messages", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "git+https://github.com/RaddyTheBrand/Nodejs-EJS-Flash-Messages.git" }, "keywords": [], "author": "", "license": "ISC", "bugs": { "url": "https://github.com/RaddyTheBrand/Nodejs-EJS-Flash-Messages/issues" }, "homepage": "https://github.com/RaddyTheBrand/Nodejs-EJS-Flash-Messages#readme", "dependencies": { "connect-flash": "^0.1.1", "cookie-parser": "^1.4.5", "ejs": "^3.1.6", "express": "^4.17.1", "express-session": "^1.17.2" } }
Note that the version of the dependencies might change in the future.
Project Structure
Our project is going to be simple. We just need our main application file which we will call ‘app.js‘ and we need a home page file which we will call ‘index.ejs‘.
📂 node_modules 📂 views 📂 pages 📜 index.ejs 🌍 app.js 📜 package-lock.json 📜 package-json
Creating our application – app.js
Instead of splitting everything into a separate section, I have briefly explained what each line of code does.
// Require the NPM packages that we need const express = require('express'); const session = require('express-session'); const cookieParser = require('cookie-parser'); const flash = require('connect-flash'); // Initalise a new express application const app = express(); // Set a default environment port or cutom port - 5000 const port = process.env.PORT || 5000; // This allows us to pass data from the form app.use(express.urlencoded({extended: true})); app.use(express.json()); // Set Cookie Parser, sessions and flash app.use(cookieParser('NotSoSecret')); app.use(session({ secret : 'something', cookie: { maxAge: 60000 }, resave: true, saveUninitialized: true })); app.use(flash()); // Setting our view engine as EJS app.set('view engine', 'ejs'); /** GET / Home Page */ app.get('/', function (req, res) { // Set a flash name and pass it to the home page. // If empty, we won't display. That's handled by EJS. const userName = req.flash('user'); res.render('pages/index', { userName } ) }); /** Post / Home Page */ app.post('/', function(req, res){ // On form submit set the flash user object to the userName input from the form req.flash('user', req.body.userName); res.redirect('/'); }); // Start out application app.listen(port); console.log(`Server is listening on port ${port}`);
Before we move on, let’s quickly reference some of the options that we used for the Cookie-Parser and Express-Sessions.
Cookie-Parser Options
cookieParser(secret, options)
Create a new cookie parser middleware function using the given secret
and options
.
secret
a string or array used for signing cookies. This is optional and if not specified, will not parse signed cookies. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.options
an object that is passed tocookie.parse
as the second option. See cookie for more information.decode
a function to decode the value of the cookie
Source: https://expressjs.com/en/resources/middleware/cookie-parser.html
Session Options
cookie
Settings object for the session ID cookie. The default value is { path: '/', httpOnly: true, secure: false, maxAge: null }
.
cookie.expires
Specifies the Date
object to be the value for the Expires
Set-Cookie
attribute. By default, no expiration is set, and most clients will consider this a “non-persistent cookie” and will delete it on a condition like exiting a web browser application.
resave
Forces the session to be saved back to the session store, even if the session was never modified during the request. Depending on your store this may be necessary, but it can also create race conditions where a client makes two parallel requests to your server and changes made to the session in one request may get overwritten when the other request ends, even if it made no changes (this behavior also depends on what store you’re using).
The default value is true
, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case. Typically, you’ll want false
.
How do I know if this is necessary for my store? The best way to know is to check with your store if it implements the touch
method. If it does, then you can safely set resave: false
. If it does not implement the touch
method and your store sets an expiration date on stored sessions, then you likely need resave: true
.
rolling
Force the session identifier cookie to be set on every response. The expiration is reset to the original maxAge
, resetting the expiration countdown.
The default value is false
.
With this enabled, the session identifier cookie will expire in maxAge
since the last response was sent instead of in maxAge
since the session was last modified by the server.
This is typically used in conjuction with short, non-session-length maxAge
values to provide a quick timeout of the session data with reduced potential of it occurring during on going server interactions.
Note When this option is set to true
but the saveUninitialized
option is set to false
, the cookie will not be set on a response with an uninitialized session. This option only modifies the behavior when an existing session was loaded for the request.
saveUninitialized
Forces a session that is “uninitialized” to be saved to the store. A session is uninitialized when it is new but not modified. Choosing false
is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing false
will also help with race conditions where a client makes multiple parallel requests without a session.
The default value is true
, but using the default has been deprecated, as the default will change in the future. Please research into this setting and choose what is appropriate to your use-case.
Note if you are using Session in conjunction with PassportJS, Passport will add an empty Passport object to the session for use after a user is authenticated, which will be treated as a modification to the session, causing it to be saved. This has been fixed in PassportJS 0.3.0
Source: https://www.npmjs.com/package/express-session
Now let’s build or home page and the form inside it.
Building our Home page using EJS
We’ll keep the page simple. Let’s create a very basic file with the ‘userName‘ object that we are passing from ‘app.js‘.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Flash Messages</title> </head> <body> <h1>Hello <%= userName %></h1> <form action="/" method="POST"> <label for="userName">Name:</label> <!-- name - userName is what we use to grab the data --> <input type="text" name="userName"><br><br> <button type="submit">Submit</button> </form> <% if(userName != '') { %> <h1 style="color: green; font-family: Arial, Helvetica, sans-serif;">Your form has been submitted. Thank you, <%= userName %></h1> <% } %> </body> </html>
Finally, let’s run our application and submit the form.
To run this, open your console and run “app.js” with node by doing the following:
node app.js
This should run the application and you should be able to the website we just created under ‘localhost:5000‘.
That’s everything from this super quick tutorial. I hope that you found it useful.
More Resources:
Thank you for reading this article. Please consider subscribing to my YouTube Channel. It’s FREE!
Ꮩery good blog! Do yoս have any tips for aspiring writers?
I’m hoping to start my own site soon but I’m a little lost on eveгything.
Wօuld you recommend starting ԝith a free platform like WordPress or
go for a pɑid option? There are so many choiⅽes оut there that I’m totally ϲοnfused ..
Any suɡgestions? Thank yoս!
My tip would be to just start. It doesn’t matter too much if you are on a paid platform or not when you are starting out. Saying this, there are benefits to owning your website.
I do like the self-hosted WordPress and that would be my first recommendation. Easy to use, great for SEO, amazing plugins, themes and you can do pretty much anything you wish with it. As long as you are tech-savvy and you can set up a WordPress blog, you should be good.
What are the other platforms that you are thinking of using?
Shameless plug, but if you are thinking of hosting your own WordPress website and registering a professional domain name check out Hostinger (affiliate link below). It’s super cheap, easy to use and you get a free domain with it.
https://www.hostg.xyz/aff_c?offer_id=408&aff_id=69300
I hope this helps and if you have any other questions I’ll be happy to answer.