30

Hi I have some newbie questions about the use of res (Express response object) and res.locals in Express.

While studying nodejs in one of the code examples There is a middleware (messages.js), a server (app.js) and the template (messages.ejs). Looking into the sample code for the template. It appears that although messages and removeMessages() is assigned to res.locals. You can access them using messages or removeMessages() without prefixing the call with locals. I wish to know the following:

  1. Are they pointing to the same objects?
  2. If they are the same does it matter if I assign to res direct instead of res.locals?

Sample Code

messages.js

var express = require('express');
var res = express.response;
res.message = function (msg, type) {
    type = type || 'info'
    var sess = this.req.session;
    sess.messages = sess.messages || [];
    sess.messages.push({
        type: type,
        string: msg
    });
};
res.error = function (msg) {
    return this.message(msg, 'error');
};
module.exports = function (req, res, next) {
    res.locals.messages = req.session.messages || [];
    res.locals.removeMessages = function () {
        req.session.messages = [];
    };
    next();
};

app.js(partial code)

var express = require('express');
var messages = require('./lib/messages');
var app = express();
app.use(messages);

messages.ejs

<% if(locals.messages) { %>
    <% messages.forEach(function (message) { % %>
        <p class = '<%= message.type %>' > <%= message.string %> < /p>
    <% }) %>
    <% removeMessages(); %>
<% } %>
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
seetdev
  • 577
  • 1
  • 5
  • 11

1 Answers1

44

res.locals is an object passed to whatever rendering engine your app is using (in this case ejs). They'll be 'global' in the render, so you don't need to prepend anything on to them to use them.

Say we wanted our server to pick up our JavaScript from S3 when in production mode, but use the local copies when in development. res.locals makes this easy. We'd have middleware along these lines in app.js:

if ('production' === app.get('env')) {
  res.locals.jsLocation = 'https://s3.amazonaws.com/kittens/js/'
} else {
  res.locals.jsLocation = '/js/';
}

and index.ejs would be something like this:

<script src="<%= jsLocation %>angular.min.js"></script>
<script src="<%= jsLocation %>myAngularFile.js"></script>
SomeKittens
  • 38,868
  • 19
  • 114
  • 143
  • 2
    So does it mean that if I were to do the code listed below. res.locals.messages is exposed in the ejs while res.nonLocalmessages is not and cannot be accessed. `module.exports = function (req, res, next) { res.locals.messages = req.session.messages || []; res.nonLocalmessages = req.session.messages || []; next(); };` – seetdev Jun 06 '14 at 00:45
  • 2
    @user3247380 You are correct. You could reference it in ejs as `messages` – SomeKittens Jun 06 '14 at 00:45