Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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)
)
like image 935
aeyang Avatar asked Sep 23 '12 05:09

aeyang


People also ask

What is RES locals in Express?

The res. locals is an object that contains the local variables for the response which are scoped to the request only and therefore just available for the views rendered during that request or response cycle.

What does res sendFile do?

The res. sendFile() function basically transfers the file at the given path and it sets the Content-Type response HTTP header field based on the filename extension.

Is Expressjs obsolete?

Express is not being deprecated. The current version is Express 4. Express 5 is on the way to being introduced. Some features of Express 4 will be deprecated in 5.

Is Expressjs good for production?

It's fast, unopinionated, and has a large community behind it. It is easy to learn and also has a lot of modules and middleware available for use. Express is used by big names like Accenture, IBM, and Uber, which means it's also great in a production environment.


2 Answers

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

  • https://groups.google.com/d/msg/express-js/72WPl2UKA2Q/dEndrRj6uhgJ

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
like image 186
zemirco Avatar answered Sep 19 '22 16:09

zemirco


If you are using express.session() you must call your function AFTER express.session() but BEFORE app.router, inside of app.configure().

app.js

app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.session());

  // Give Views/Layouts direct access to session data.
  app.use(function(req, res, next){
    res.locals.session = req.session;
    next();
  });

  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

index.jade

extends layout

block content   
  h1= title   
  p My req.session.var_name is set to #{session.var_name}
like image 35
Adam Albright Avatar answered Sep 16 '22 16:09

Adam Albright