Having a hard time trying to understand 'next/next()' in express.js
This is an example of it:
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
(etc.)
app.get('/memo', function(req, res) {
console.log("index");
Memo.find({}, function(err, data) {
if(err) return next(err);
res.render('index', { memos: data });
});
});
And here is another one:
app.get('/memo/list', function(req, res, next) {
console.log("get memos");
Memo.find({}, function(err, data) {
if(err) return next(err);
res.json(data);
});
});
Taken from a simple memo pad built on node
These are the questions that are puzzling me:
- What does exactly
next/next();
do? What would happen if it is not present? - Why is the second part taking
next
as a parameter and the first isn't?
EDIT:
Solution 1:
Express uses middleware functions that have callbacks (functions that get called when an action is completed), and next has that purpose (it's a callback that triggers the next middleware in the Express stack). All Express middleware (that is Connect compatible) have 3 params: request, response, next (which is optional).
For example the static middlware serves static files, the csrf middleware checks for a param when receiving POST requests and the router middleware that handles the routes (what you've pasted above is part of that).
Each middleware can complete it's task and call the next
middleware in the queue if some conditions are met (for example the static middleware won't call a next middleware, because it will take care on itself to serve the files, so that the router won't get called).
In the router you don't usually call next
because it tends to be the last middleware executed (unless you want something like benchmarking).
If you wanted to create a middleware that denies access to all users that aren't logged in, you would have to call next()
only if the user is logged in (so that the next middleware is called, the router in this case and the user can access the page they're looking for), else you would probably redirect them to the login page.
next
takes either no parameters at all or an error as a parameter.
Edit: based on your configuration the router is before the static middleware, so if you want files to be served you need to declare a wildcard route that calls next() when the route isn't matched:
app.get('*', function (req, res, next) {
// no route is matched
// so call next() to pass to the static middleware
next();
});
Note: I don't recommend you put the static file server after the router, I suggest you put it before so you can define your own custom 404 routes.