node.js - connect-flash does not seem to be passed on to res.locals.success_msg - Stack Overflow

admin2025-04-17  1

I'm trying to set a flash message based on npm connect-flash but it fails to pass on the message. It seems as if res.locals.success is not set and I have no clue why... If I do

res.locals.success_msg = 'great';

Then it does show the message on the html page

I installed all required packages: `

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
require('dotenv').config(); // Load environment variables

const app = express();
const PORT = process.env.PORT || 3000; // Use the port from .env or default to 3000
const session = require('express-session');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo'); 
const mongoURI = process.env.MONGO_URI || 'mongodb://localhost:27017/sessionDB';
const flash = require('connect-flash');

// Connect to MongoDB with mongoose
mongoose.connect(mongoURI)
  .then(() => {
    console.log('Connected to MongoDB');
  })
  .catch((err) => {
    console.error('MongoDB connection error:', err);
  });

// Define middleware
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(express.json());
app.use(flash());

// Session setup - generates a session cookie to use for logged in user
app.use(
    session({
        secret: process.env.COOKIE_SECRET || "er@(-_45rgD",
        resave: false,
        saveUninitialized: true, 
        cookie: { 
            secure: false, 
            maxAge : 5 * 60 * 1000, 
            sameSite: 'Strict' 
        }, 
        store: MongoStore.create({
            mongoUrl: mongoURI, 
            collectionName: 'sessions', 
            ttl: 14 * 24 * 60 * 60, 
        }),
    })
);

// Middleware to pass flash messages to views
app.use((req, res, next) => {
    console.log('flash sucess before setting locals:', req.flash('success_msg'));  // Logs flash messages before setting locals
    console.log('flash error before setting locals:', req.flash('error_msg'));  // Logs flash messages before setting locals
    res.locals.success_msg = req.flash('error_msg')[0] || ''; 
    res.locals.error_msg = req.flash('error_msg')[0]|| ''; 
    console.log('locals after setting:', res.locals);  // Logs locals object after setting flash messages
    next();
});

// Define routes

app.get('/flashsuccess', async (req, res) => {
    console.log('flashsuccess');
    req.flash('success_msg', 'This is a success message');
    res.redirect('/');
});

app.get('/flasherror', async (req, res) => {
    console.log('flasherror');
    req.flash('error_msg', 'This is an error message');
    res.redirect('/');
});


app.get('/', (req, res) => {
    console.log('Flash messages:', req.flash());  // Log flash messages directly
    console.log('Locals:', res.locals);  // Log locals directly
    res.render('index');  // Render with flash messages
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}`);
});
;

my index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MongoDB</title>
    <link href="/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
            <!-- Success Flash Message -->
            <% if (success_msg) { %>
                <div class="alert alert-success alert-dismissible fade show" role="alert">
                    <%= success_msg %>
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            <% } %>
    
            <!-- Error Flash Message -->
            <% if (error_msg) { %>
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
                    <%= error_msg %>
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            <% } %>
    <a href="flashsuccess">set flash success message</a><br>
    <a href="flasherror">set flash error message</a><br>

    </div>
</body>
</html>

These are the console.logs

flashsuccess
flash sucess before setting locals: [ 'This is a success message' ]
flash error before setting locals: []
locals after setting: [Object: null prototype] { success_msg: '', error_msg: '' }
Flash messages: {}
Locals: [Object: null prototype] { success_msg: '', error_msg: '' }

Tried to set the

res.locals.success_msg = 'great'

that works

I'm trying to set a flash message based on npm connect-flash but it fails to pass on the message. It seems as if res.locals.success is not set and I have no clue why... If I do

res.locals.success_msg = 'great';

Then it does show the message on the html page

I installed all required packages: `

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
require('dotenv').config(); // Load environment variables

const app = express();
const PORT = process.env.PORT || 3000; // Use the port from .env or default to 3000
const session = require('express-session');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo'); 
const mongoURI = process.env.MONGO_URI || 'mongodb://localhost:27017/sessionDB';
const flash = require('connect-flash');

// Connect to MongoDB with mongoose
mongoose.connect(mongoURI)
  .then(() => {
    console.log('Connected to MongoDB');
  })
  .catch((err) => {
    console.error('MongoDB connection error:', err);
  });

// Define middleware
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(express.json());
app.use(flash());

// Session setup - generates a session cookie to use for logged in user
app.use(
    session({
        secret: process.env.COOKIE_SECRET || "er@(-_45rgD",
        resave: false,
        saveUninitialized: true, 
        cookie: { 
            secure: false, 
            maxAge : 5 * 60 * 1000, 
            sameSite: 'Strict' 
        }, 
        store: MongoStore.create({
            mongoUrl: mongoURI, 
            collectionName: 'sessions', 
            ttl: 14 * 24 * 60 * 60, 
        }),
    })
);

// Middleware to pass flash messages to views
app.use((req, res, next) => {
    console.log('flash sucess before setting locals:', req.flash('success_msg'));  // Logs flash messages before setting locals
    console.log('flash error before setting locals:', req.flash('error_msg'));  // Logs flash messages before setting locals
    res.locals.success_msg = req.flash('error_msg')[0] || ''; 
    res.locals.error_msg = req.flash('error_msg')[0]|| ''; 
    console.log('locals after setting:', res.locals);  // Logs locals object after setting flash messages
    next();
});

// Define routes

app.get('/flashsuccess', async (req, res) => {
    console.log('flashsuccess');
    req.flash('success_msg', 'This is a success message');
    res.redirect('/');
});

app.get('/flasherror', async (req, res) => {
    console.log('flasherror');
    req.flash('error_msg', 'This is an error message');
    res.redirect('/');
});


app.get('/', (req, res) => {
    console.log('Flash messages:', req.flash());  // Log flash messages directly
    console.log('Locals:', res.locals);  // Log locals directly
    res.render('index');  // Render with flash messages
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}`);
});
;

my index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MongoDB</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
            <!-- Success Flash Message -->
            <% if (success_msg) { %>
                <div class="alert alert-success alert-dismissible fade show" role="alert">
                    <%= success_msg %>
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            <% } %>
    
            <!-- Error Flash Message -->
            <% if (error_msg) { %>
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
                    <%= error_msg %>
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            <% } %>
    <a href="flashsuccess">set flash success message</a><br>
    <a href="flasherror">set flash error message</a><br>

    </div>
</body>
</html>

These are the console.logs

flashsuccess
flash sucess before setting locals: [ 'This is a success message' ]
flash error before setting locals: []
locals after setting: [Object: null prototype] { success_msg: '', error_msg: '' }
Flash messages: {}
Locals: [Object: null prototype] { success_msg: '', error_msg: '' }

Tried to set the

res.locals.success_msg = 'great'

that works

Share edited Jan 31 at 0:47 Patrik Horemans asked Jan 31 at 0:38 Patrik HoremansPatrik Horemans 112 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I have found the issue.
When you invoke console.log(req.flash('success_msg')); it clears/destroys the flash message. So if you would read it again, so another console.log(req.flash('success_msg')); then it will be empty.

And since I'm reading it

console.log('flash sucess before setting locals:', req.flash('success_msg'));  // Logs flash messages before setting locals
console.log('flash error before setting locals:', req.flash('error_msg'));  // Logs flash messages before setting locals
res.locals.success_msg = req.flash('error_msg')[0] || ''; 
res.locals.error_msg = req.flash('error_msg')[0]|| ''; 

It is already empty where I want to store it in the res.locals

转载请注明原文地址:http://anycun.com/QandA/1744884918a88998.html