node.jsejsexpress-4connect-flash

Flash Message from ejs in Express 4


I am trying to show a confirmation message before user deletes anything. I've tried following various related sources that I found in internet, but couldn't get them to work. I am using EJS template and Express 4.

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();
var flash = require('connect-flash');
var session = require('express-session');

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use('/js', express.static(__dirname + '/node_modules/bootstrap/dist/js')); // redirect bootstrap JS
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); // redirect CSS bootstrap


// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));

app.use(session({ secret: 'zxcv' })); // session secret
app.use(flash()); // use connect-flash for flash messages stored in session

app.use('/', routes);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function (err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

app.listen(8000);
module.exports = app;

index.js

var express = require('express');
var router = express.Router();

var searchModule = require('../crud_module/search.js');
var updateModule = require('../crud_module/update.js');
var deleteModule = require('../crud_module/delete.js');


/* GET home page. */
router.get('/', function (req, res) {
    res.render('index', { title: '' });
});

router.post('/search-results', function (req, res) {
    searchModule.search(req.body, function (data) {
        res.render('index', { title: '', results: data });
    });
});

router.post('/edit-data', function (req, res) {
    searchModule.searchById(req.body, function (data) {
        res.render('edit', { title: '', results: data });
    });
});

router.post('/save-changes', function (req, res) {
    if (req.body.change == "update") {
        updateModule.saveChanges(req.body, function (err) {
            if (err) {
                res.render('edit', { message: req.flash('Error', 'Error Occured') });

            } else {
                //req.flash('success', 'Your name was updated');
                res.render('edit', { message: req.flash('success', 'Data was updated')) });
            }
            res.redirect('/edit-data');
        });
    }
if (req.body.change == "delete") {
        deleteModule.deleteRecord(req.body, function (data) {
            res.render('edit', { title: 'Volume Tracker', confirmation: data });

        });
    }
});


module.exports = router;

edit.ejs

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
    <link href="node_modules/popups/css/popupS.min.css" rel="stylesheet" />
    <script type="text/javascript" src="https://gc.kis.scr.kaspersky-labs.com/5B1FA715-F8FF-784F-A4C9-0D867337CB3D/main.js" charset="UTF-8"></script><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="node_modules/elasticsearch/src/elasticsearch.angular.js"></script>
    <script src="node_modules/popups/dist/popupS.min.js"></script>
    <script language="javascript">

    </script>
<style type="text/css">


</style>

</head>

<body>
<br>

<form action='/save-changes' method='post'>
<div class="container">



    <% if(locals.results) { %>
      <table class="table table-bordered table-hover table-condensed"> 
        <tr>
            <th  bgcolor="silver">Term Key</th>
            <td>
              <input name="termKey"  value= "<%= results[0]._source.termkey %>" style="border:none; width:100%"/>
            </td>
          </tr>

          <tr>
            <th bgcolor="silver">Active</th>
            <td>
              <input name="active" value= "<%= results[0]._source.active %>" style="border:none; width:100%"/>
            </td>
          </tr>

          <tr>
            <th bgcolor="silver">Term Description</th>
            <td>
              <input name="termDescription" value= "<%= results[0]._source.termdescription %>" style="border:none; width:100%"/>
            </td>
          </tr>


      </table>  
      <div align="center">
      <button type="submit" class="btn btn-info" name="change" value="update"> Save Changes </button>
      <button type="submit" class="btn btn-danger" name="change" value="delete"> Delete Record </button>
      </div>


    <% } %>
    </form>
    <br>

    </div>

    </body>
    </html>

Here, when the user will click on the delete button, a confirmation message will be shown (here--> in index.js, I first tried showing confirmation message after user updates anything; which didn't work either). But whenever I try to include this:

    <% if (message.length > 0) { %>
            <div class="alert alert-danger"><%= message %></div>
        <% } %>
in edit.ejs , I get error:
ReferenceError: 
    92|     </form>
    93|     <br>
 >> 94|     <% if (message.length > 0) { %>
    95|         <div class="alert alert-danger"><%= message %></div>
    96|     <% } %>




 message is not defined
        at eval (eval at <anonymous> (\ElasticSearch\ES\VolumeTracker\VolumeTracker\node_modules\ejs\lib\ejs.js:495:12), <anonymous>:41:12)
    at Template.compile.returnedFn (\ElasticSearch\ES\VolumeTracker\VolumeTracker\node_modules\ejs\lib\ejs.js:524:17)
    at View.exports.renderFile [as engine] (\ElasticSearch\ES\VolumeTracker\VolumeTracker\node_modules\ejs\lib\ejs.js:378:31)
    at View.render (\ElasticSearch\ES\VolumeTracker\VolumeTracker\node_modules\express\lib\view.js:76:8)
    at Function.app.render (\ElasticSearch\ES\VolumeTracker\VolumeTracker\node_modules\express\lib\application.js:527:10)
    at ServerResponse.res.render (\ElasticSearch\ES\VolumeTracker\VolumeTracker\node_modules\express\lib\response.js:900:7)
    at \ElasticSearch\ES\VolumeTracker\VolumeTracker\routes\index.js:22:13
    at \ElasticSearch\ES\VolumeTracker\VolumeTracker\crud_module\search.js:45:9
    at tryCallOne (\ElasticSearch\ES\VolumeTracker\VolumeTracker\node_modules\elasticsearch\node_modules\promise\lib\core.js:37:12)
    at \ElasticSearch\ES\VolumeTracker\VolumeTracker\node_modules\elasticsearch\node_modules\promise\lib\core.js:123:15

Solution

  • I am posting here answer to my own question, in case anyone needs the same thing. To pass flash message to view, in your app.js ensure the following is present (note I am using ejs template for view) :

    var express = require('express');
    var path = require('path');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');
    
    var app = express();
    var flash = require('connect-flash');
    var session = require('express-session');
    
    app.use(cookieParser());
    app.use(session({ secret: 'zxcv' })); // session secret
    app.use(flash()); // use connect-flash for flash messages stored in session
    

    in your index.js

    router.post('/edit', function (req, res) {
        if (req.body.change == "update") { //if update btn is clicked
            updateModule.saveChanges(req.body, function (err) { //call update module
                if (err) {
                    //if error
                    req.flash("msg","Error Occured");
                    res.locals.messages = req.flash();
                    res.render('edit', { title: 'myApp'});
                } else {
                    //on success
                    req.flash("msg", "Data updated successfully");
                    res.locals.messages = req.flash();
                    res.render('index', { 'title': 'myApp'});
                 }
    
            });
        }
    });
    

    and here is my view: for editing--> edit.ejs

    <body>
    <form action='/edit' method='post'>
    <!--your data-->
    <script language="javascript">
        function UpdateConfirm() {
                   var userPreference;
                   if (confirm("Do you want to save changes?") == true) {
                   return true;} 
                   else {
                   return false;}
    
                   }
        </script>
          <button type="submit" class="btn btn-info" name="change" value="update" onClick= "<%- "return UpdateConfirm()" %>" > Save Changes </button>
    
    </form>
    </body>
    

    Here, if you click on the button, it will first popup a confirmation alert box (will call UpdateConfirm()), and if you click yes then it will submit the form. Now, after updating I am passing flash message from my index.js. The view where you want to show the flash message, put this:

    <% if (locals.messages) { %>
    
        <script language="javascript">
        alert("<%= messages.msg %>");
        </script>
    
            <% } %>
    

    It will show the message in an alert box. P.S: You have to install these npm packages: cookie-parser,connect-flash and connect-flash