Search code examples
node.jssessionexpressresponsepug

ExpressJS 3.0 How to pass res.locals to a jade view?


I want to display a flash message after a user fails to sign in but I just can't get the variables to show up in my Jade views.

I have some pieces, I know I have to use this in my app.configure():

    app.use (req, res, next) ->
      res.locals.session = req.session

And I'll set what the flash message is after the user POSTS the wrong password:

     exports.postSession = (req, res) ->
       users = require '../DB/users'
       users.authenticate(req.body.login, req.body.password, (user) ->
       if(user)
         req.session.user = user
         res.redirect(req.body.redirect || '/')
       else
         req.session.flash = 'Authentication Failure!'
         res.render('sessions/new', {title:'New', redirect: req.body.redirect })
      )

I don't know how to access res.locals.session in my Jade file. I doubt I am setting everything up right. This question is a lot like this one: Migrating Express.js 2 to 3, specifically app.dynamicHelpers() to app.locals.use? but I still can't get it to work. It would be much appreciated if someone could show me just a simple example of setting values in res.local and accessing them in a view.

p.s. I do know about connect-flash but I need to understand how to make things available in views.

This is my app:

app.configure(() -> 
  app.set('views', __dirname + '/views')
  app.set('view engine', 'jade')
  app.use(express.bodyParser())
  app.engine('.jade', require('jade').__express)
  app.use(express.methodOverride())
  app.use(express.cookieParser())
  app.use(express.session({ store: new express.session.MemoryStore({reapInterval: 50000 * 10}), secret: 'chubby bunny' }))
  app.use(express.static(__dirname + '/public'))
  app.use((req, res, next) ->
    res.locals.session = req.session
    next()
  )
  app.use(app.router)
)

Solution

  • Just to give a short summary for everyone who has the same problem and got the impression that is was solved changing res.redirect.

    It is very important to put your app.use middleware before app.router. See the comments by TJ Holowaychuck, the author of express

    Here is an example using a fresh installation of express v3.0.0rc4

    app.js:

    app.use(function(req, res, next){
      res.locals.variable = "some content";
      next();
    })
    
    app.configure(function(){
      app.set('port', process.env.PORT || 3000);
      app.set('views', __dirname + '/views');
      app.set('view engine', 'jade');
      app.use(express.favicon());
      app.use(express.logger('dev'));
      app.use(express.bodyParser());
      app.use(express.methodOverride());
      app.use(app.router);
      app.use(express.static(path.join(__dirname, 'public')));
    });
    

    index.jade:

    extends layout
    
    block content
      h1= title
      p Welcome to #{title}
      p= variable