I have the following instead of app.locals.use
app.use (req,res,done) ->
res.locals.flash = '<li>uh oh!</li>';
In my Jade file, I do:
!{flash}
I keep receiving errors saying that flash isn't defined..
make sure that you defined that middleware near the top (anywhere above app.router) so that it's invoked before the routes, and make sure to call done()
The positioning of it fixed it! :) Thanks TJ
I've got a very similar issue, and it's not behaving as I would expect
//Load Express
var express = require('express');
var app = express.createServer();
//Configure View
var cons = require('consolidate');
app.engine('html', cons.ejs);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
//Render '/'
app.get('/', function (req, res) {
res.render('home');
});
//Add Local
app.use(function (req, res, next) {
res.locals.message = 'Hello World';
});
app.listen(8080);
The thing to note is that app.use is after app.get and this causes the exception in the view
ReferenceError: C:\github\temp\views\home.html:1
>> 1| <%- message %>
message is not defined
Since I never have app.use(app.router), the router should be the last thing to be added? Even if I manually add app.router at the end, I get the same problem?
if you dont explicitly .use(app.router) the first call to app.VERB() will use() it, so that's why you're seeing your locals.message one mounted _below_ app.router. It's a little obscure I know but I'll make sure this is well documented this time around
the alternative would be that we force app.use(app.router) in every app but that could cause other problems
The problem is that even if I choose to manually add app.use(app.router) to the end of my application, it still get's added as soon as the first verb is used.
yeah, that's because app.use(app.router) hasn't happened yet, which is natural as far as statement execution goes, precedence definitely matters here
So as soon as you call a verb, it inserts the router? Making subsequently inserting the router pointless?
yup because it's already done that behind the scenes, technically you can .use() it as many times as you want but I cant think of any reason you would want the router several times haha, you could though
hmm, I guess I can live with this, but it's not the semantics I'd like. I feel like either the router should be split up, so that you can have any series of verbs/middleware in any order (verbs would be just like any other middleware) or there should be a way to have complete control over when the router gets called.
the thing is .use() is effectively just a .push() to an array, which is very flexible, though yes you have to keep precedence in mind. I have a branch where each .VERB() call produce its own middleware, which is fundamentally more elegant but it is quite a bit slower
Would it be possible for using app.router to remove any previous uses of app.router so each router could only be used exactly once? This would only need to happen as the server started, which would minimise the performance cost. Alternatively, the approach of each verb creating it's own middle ware could be used, but with a 'consolidate' stage once the server is completely defined, that way you could consolidate methods into routers in order to maintain performance?
the locals.use method actually solved this use case for me, since it let me define some middleware to be called before rendering views, regardless of where it was defined. The reason I want to do that is to keep things in modules where functionally related things are in the same module.
that would be a lot of beating around the bush just for a simple precedence issue, which is not really much of an issue, maybe a bit of a GOTCHA but however you're bootstrapping the app should easily be able to take care of this sort of thing. As far as manipulating the middleware stack on subsequent .use()es etc would violate the simplicity of middleware as they are currently, which have the simple rule of being called in order of definition, anything else would lead to more confusion. I think this just needs to be clearly documented since the auto-use() part here is a little magical
ok, I'll learn to live with it
Hi Visionmedia,
I have similar issue with express 3.0.0rc3. If I add app.use(app.router) at end my browser spins and home page does not load. Otherwise I get error message: 'message is not defined' while rendering page
app.use(app.router);
app.use(function(req, res){
res.locals.message = 'good';
});
I dont get error is I specified locals.message in jade template. Have spent lot of time troubleshooing.
Your help is appreciated.
Thank you.
move app.use(app.router) below, and you need to call next()
Thanks a lot Jonathan it worked.
added next();
and moved app.use(app.router) at end
Most helpful comment
make sure that you defined that middleware near the top (anywhere above app.router) so that it's invoked before the routes, and make sure to call
done()