doctopus
doctopus

Reputation: 5657

Can't get flash message to render when using connect-flash for Node/Express app

I'm trying to render flash messages via connect-flash when users successfully login to my app.

I can console log out the flash messages, but they don't seem to be getting rendered client side.

However, I know for a fact that there's nothing wrong in the client side because when I replace req.flash[0] in my route with a simple string like 'You have successfully login!' then the message does appear.

Passport config:

// Local login Strategy
passport.use('local-login', new LocalStrategy(
  {
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback: true
  },
  (req, email, password, done) => {
    User.findOne({ 'local.email': email })
      .then(user => {
        if (!user) return done(null, false);

        user.validPassword(password, (err, res) => {
          if (err) return done(err);
          if (!res) return done(null, false);
          done(null, user, req.flash('success', 'Login Successful!'));
        });
      })
      .catch(err => done(err));
  }
));

Route:

app.post(
    '/api/login',
    passport.authenticate('local-login'),
    (req, res) => {
      console.log(req.flash('success'));
      const user = {
        user: req.user,
        msg: req.flash('success')[0]       // Works when I replace with 'You have successfully logged in'
      };
      res.send(user);
    }
  );

Server:

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const passport = require('passport');
const flash = require('connect-flash');
const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session');
const keys = require('./config/keys');
require('./models/User');
require('./services/passport');

mongoose.connect(keys.mongoURI);

const app = express();

app.use(bodyParser.json());
app.use(cookieParser());
app.use(flash());


app.use(
  cookieSession({
    maxAge: 30 * 24 * 60 * 60 * 1000,
    keys: [keys.cookieKey]
  })
);

app.use(passport.initialize());
app.use(passport.session());

require('./routes/authRoutes')(app);

app.get('/', (req, res) => {
  res.json({ message: 'hello' });
});

if (process.env.NODE_ENV === 'production') {
  app.use(express.static('client/build'));

  const path = require('path');
  app.get('/', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
  });
}

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log('Working'));

Upvotes: 2

Views: 1409

Answers (2)

iwaduarte
iwaduarte

Reputation: 1700

The idea behind req.flash is to use with redirects (res.redirect) and only display once so you do not need to repeat code. I have too struggled with it for a while until I figured that would make my routes more robust (especially if you are going to the database to fetch data AND need to display the error message).

Most people would do that way:

callDatabase().then ((data)=>{
res.render('samepage', data: data, error: error.message)
})

and this would be repeated across several routes if they need to find the specific data over and over again (i.e validation purposes).

An elegant way of doing it would be create a specific router to fetch the specific data AND deal with errors by using a session approach with, in this case, the connect-flash module so:

router.get('/findData', (req,res)=>{
callDatabase().then( (data)=> res.render('index',data));
});

and then :

router.get('whatever', (req,res)=>{
// error in something
 req.flash('error', 'Show this error based on this router!')
  res.redirect('/findData');

});

That way you could always rely on the router.get('/findData').. by simply saving your errors and redirecting later on.

Upvotes: 1

doctopus
doctopus

Reputation: 5657

Weird problem, but turns out by calling console.log(req.flash('success') before incorporating it into the response actually made it fail. Once I removed the console log line it started working.

Not sure why this is - not sure why this is, if anyone has any idea would love to know.

Upvotes: 2

Related Questions