Nodejs Flash messages only loads after the page is refreshed (connect-flash) - node.js

I'm getting stuck with connect-flash , all flash messages doesn't load on the page unless I refresh for a couple of times I'm not sure why.
I created a small project just to test connect-flash and it's the same result, please check the code below:
App.js code:
const express = require('express');
const path = require('path');
const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const session = require('express-session');
const flash = require('connect-flash');
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}));
//using flash
app.use(flash());
app.use(function(req, res, next){
res.locals.success = req.flash('success');
res.locals.error = req.flash('error');
next();
});
//flash route
app.get('/flash', (req, res) =>{
req.flash("success", "CONNECT FLASH TEST");
res.render('flash');
});
const port = process.env.PORT || 5000;
app.listen(port, () =>{
console.log(`App has started on port ${port}`);
})
Here's the code for the flash.hbs page to render the flash message:
<h1>Flash page</h1>
{‌{#if success}}
<h2>{‌{success}}</h2>
{‌{/if}}
Thanks so much in advanced, any help would be highly appreciated guys.

Do they render after just one refresh? That's how they are supposed to work.
"Flash messages" are used to carry a message over to the next request, and most of the time the only reason is the post-request-get pattern. If you just want to show a message to the user on the same page, while not doing a redirect, you don't need a library for it. Just pass the message to the template as data.

I was halfway through rolling my own new version of req.flash, when I was looking through the docs of express-session and came across this gem:
Note Since version 1.5.0, the cookie-parser middleware no longer needs to be used for this module to work. This module now directly reads and writes cookies on req/res. Using cookie-parser may result in issues if the secret is not the same between this module and cookie-parser.
And lo, I had these lines:
app.use(require('cookie-parser')())
const session = require('express-session')
const MongoStore = require('connect-mongo')(session)
app.use(session({
secret: process.env.SESSION_STORE_SECRET,
store: new MongoStore({mongooseConnection: mongoose.connection}),
maxAge: 10*365*24*60*60*1000, // set to 10 years
resave: false,
saveUninitialized: false
}))
Once I changed the cookie-parser line to:
app.use(require('cookie-parser')(process.env.SESSION_STORE_SECRET))`
it worked exactly as expected!
(For some people, the answer will be to remove cookie-parser altogether.)

Related

ReferenceError: done is not defined

const express = require('express');
const cookieParser = require('cookie-parser');
const port = 8000;
const app = express();
const expressLayout = require('express-ejs-layouts');
const db = require('./config/mongoose')
// used for session cookie
const session = require('express-session')
const passport = require('passport')
const passportLocal = require('./config/passport-local-strategy')
app.use(express.urlencoded())
app.use(cookieParser());
// where to look static files like css,js
app.use(express.static('./assets'))
// this line must be above the routes line (line no. 11 in this case) because in the routes all the views are going to be render and before that we have to tell to the browser the layout
app.use(expressLayout)
// extract style and scripts from sub pages into the layout
app.set('layout extractStyles', true);
app.set('layout extractScripts', true);
// set up the view engine
app.set('view engine', 'ejs');
app.set('views', './views');
app.use(session({
name: 'iFacebook',
// TODO change the secret before deployment in production mode
secret: 'Coder',
saveUninitialized: false,
resave: false,
cookie: {
maxAge : (1000*60*100)
}
}))
app.use(passport.initialize());
app.use(passport.session())
// use express router
// require('./routes/index) is similar to require('./routes) in this case, it by default fetch routes
app.use('/', require('./routes/index'))
app.listen(port, (err) => {
if (err) {
console.log(`Error in running the server : ${err}`);
}
console.log(`Server is listening at ${port}`);
})
I am using passport and passport-local strategy and this error comes and even i did not know from which file this error comes. I am sharing the index.js file code which is the server file. This is the first time i am using this even on the documentation i did not found anything

My express req.sessions get saved as undefined in Express v4

My express V4 app doesn't give me the correct value of the sessions instead just returns undefined. My app was structured and built using express-generator and this is my app.js file.
var express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
routes = require('./routes/index'),
app = express(),
compression = require('compression'),
session = require('express-session');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.set('view cache', true);
app.enable('trust proxy');
app.use(session({
secret: "Share3na Network!195",
resave: true,
saveUninitialized: true,
cookie: { secure: true, httpOnly: true }
}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(compression());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
And these are the routes the take the session value and send it back.
router.get('/getmask', function(req,res){
res.send(req.session.mask);
});
//GET the mask during event body load
router.get('/sendmask', function(req,res){
req.session.mask = striptags(emojiStrip(req.query.m));
});
In another route when I append the requests' IP address with the session value: req.ip() + req.session.mask, what gets saved in the database is "123.456.789undefined"
You need to save the session values after modification. The documentation for the same can be seen in the README of the package.
//GET the mask during event body load
router.get('/sendmask', function(req,res){
req.session.mask = striptags(emojiStrip(req.query.m));
req.session.save();
});

Bad Request trying to start node server at Azure web app

I'm trying to run my node server.js there but it's not working.
I have sent all my files over the FTP in a folder called api (wwwroot is my website, so i need to run this server inside api folder).
Do i need to do something else or what?
Here's my server.js code:
//Dependecies
var express = require('express');
var app = express();
var port = process.env.PORT || 3030;
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session')
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var passport = require('passport');
var flash = require('connect-flash');
var MongoStore = require('connect-mongo')(session);
var cors = require('./cors');
//Database Configurations
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
//Passport Strategies
require('./config/passport')(passport);
//Morgan Logger
app.use(morgan('dev'));
//Cookie Parser
app.use(cookieParser());
//bodyParser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
//Session
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
cookie: { maxAge: null, secure: false },
store: new MongoStore({
url: configDB.url,
collection: 'sessions'
})
}));
//Connect Flash
app.use(flash());
//CORS Setup
app.use(cors());
//Passport
app.use(passport.initialize());
app.use(passport.session());
//Require the Routes
require('./app/routes.js')(app, passport);
//Start Server
app.listen(port);
console.log('Server is Running!');
EDIT :
When i type in the console, it stops for a bit and print "Bad Request".
Commonly, the 400 BAD request HTTP error code means that the request could not be understood by the server due to malformed syntax. You could check your request url, or post body.
Additionally, you can use the FTP tool to check whether there is a web.config file in your root directory on Azure Web Apps environment. If not, you can manually create one, you can refer to https://tomasz.janczuk.org/2011/08/hosting-express-nodejs-applications-in.html for a sample for an express based application.
Meanwhile, you can refer to https://learn.microsoft.com/en-us/azure/app-service-web/app-service-web-nodejs-best-practices-and-troubleshoot-guide for more info about troubleshooting on node.js applications on Azure Web Apps.
Any further concern, please feel free to let me know.

Why req.session set in one route, not available in another route call?

I am using Express "express": "~4.13.1" and "express-session": "^1.11.3".
I have set my server like this :
app.js :
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var routes = require('./routes/index');
var users = require('./routes/users');
app = express();
// view engine setup
var engines = require('consolidate');
app.set('views', path.join(__dirname, 'views'));
app.engine('html', engines.mustache);
app.set('view engine', 'html');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
//Using express-session in app with secret key
app.use(session({
secret: 'mapdcs',
resave: true,
saveUninitialized: true,
cookie: {
path: '/',
httpOnly: true,
secure: false,
maxAge: null
}
}));
app.use('/', routes);
app.use('/api/users', users);
index.js :
// First call
router.post('/adduser', function(req, res, next) {
req.session.username = red.body.username;
req.session.save();
console.log('>>Session data From Add users');
console.log(req.session); //I got the username session here
}
// Second call
router.post('/check_auth', function(req, res, next) {
console.log('>> Session data From check_auth');
console.log(req.session); //Am not getting session here.
}
Am trying to solve this issue since last two days. Can any one help in this please. Thanks in advance.
You seem to have missing closing brackets ')' after the router calls, but I don't think that's the main issue. It has something to do with the request not sending a response / terminating correctly.
If you change the console.log(req.session)'s to something that sends a response e.g res.json(req.session), the second call works - see below for an example:
router.post('/adduser', function(req, res, next) {
req.session.username = red.body.username;
req.session.save();
console.log('>>Session data From Add users');
// changed console.log to res.json
res.json(req.session)
}); // Added the final closing bracket to router.post
// Second call
router.post('/check_auth', function(req, res, next) {
console.log('>> Session data From check_auth');
// Changed the second console.log to res.json
res.json(req.session);
}) // Added another closing bracket
Hope this helps!
Edit: You could also just use res.end(), res.send() or res.render() - anything that generates a response - see the Express response docs.
I changed the axios call and set withCredential to true to solve the problem.

Express js 4 and multer

I'm writing a Node js application which handles multipart form data and so I'm using multer for the purpose.
The problem is that req.body is always undefined.
Here is my code:
var app = express();
var http = require('http').createServer(app);
//All environments
app.set('port', process.env.PORT || config.ports.HTTP_PORT);
app.set('views', config.folders.views);
app.set('view engine', 'ejs');
//Express 4 dependencies
app.use(morgan('dev'));
app.use(multer({ dest: config.folders.uploads}))
app.use(cookieParser()); //Parser for cookie session
app.use(session({ secret: 'secret' }));
app.use(passport.initialize()); //Init passport
app.use(passport.session()); //Persistent login sessions
app.use(flash()); //Flash messages
//Public folder
app.use(express.static(config.folders.public));
require('./auth')(passport); //Add auth methods to passport
require('./routes')(app, passport); //Add routes
app.post('/test', function(req, res) {
console.log(req.body.test); //req.body always undefined
});
What could be the problem?
EDIT:
Now req.body is filled with data, but the req.files property is still undefined
add bodyParser with this code :
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
HTML forms need to have the enctype attribute set appropriately in order for files to be sent. Example:
<form method="POST" action="/foo" enctype="multipart/form-data">
Editing your original code:
You have to install Multer Multer Docs
npm i multer -S
const app = express();
const http = require('http').createServer(app);
const multer = require('multer'); // added, wasn't in your original code.
//All environments
app.set('port', process.env.PORT || config.ports.HTTP_PORT);
app.set('views', config.folders.views);
app.set('view engine', 'ejs');
//Express 4 dependencies
app.use(morgan('dev'));
// newly added
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(multer({ dest: config.folders.uploads}).single('file')) // added the single() method
app.use(cookieParser()); //Parser for cookie session
app.use(session({ secret: 'secret' }));
app.use(passport.initialize()); //Init passport
app.use(passport.session()); //Persistent login sessions
app.use(flash()); //Flash messages
//Public folder
app.use(express.static(config.folders.public));
require('./auth')(passport); //Add auth methods to passport
require('./routes')(app, passport); //Add routes
Testing the code:
app.post('/test', (req, res) => {
console.log(req.body.test); //req.body always undefined
console.log(req.file); // added this, it should work fine now.
});

Resources