Reputation: 13653
I'm using a function that someone else wrote for express
and passport
, which defines the middleware(?) as follows:
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()){
return next();
}
else{
req.flash('error', 'You need to be logged in to access this page');
res.redirect('/login');
}
}
This function is used in the router as follows:
app.get('/page', isLoggedIn, function(req, res){
// ...
});
What I don't understand is, shouldn't the function be called with parameters req
and res
? Maybe the callback next
is not necessary since it's the next argument of app.get
, but how does the function access req
and res
? I would expect it to be called as follows:
app.get('/page', isLoggedIn(req, res), function(req, res){
// ...
});
How does it work without specifying the arguments?
Thanks,
Upvotes: 0
Views: 827
Reputation: 48250
What I don't understand is, shouldn't the function be called with parameters req and res?
It will be called with these arguments, somewhere inside the get
function. Suppose this is the simplified get
, implemented as
// a super simple get that will expect a function
// and call the function with two arguments
function get( f ) {
var res = 1, req = 1;
f( res, req );
}
There are multiple ways of passing a function to get
. For example, you pass an anonymous function
get( function( res, req ) {
return res + req;
}
You can also pass a named function defined elsewhere
function isLoggedIn( res, req ) {
return res + req;
}
get( isLoggedIn );
This however, is not what you'd expect:
get( isLoggedIn( res, req ) );
The problem here is that
isLoggedIn( res, req )
is no longer a function declaration. It is an invocation and the result of this invocation depends on what res
and req
are. With some luck, the invocation can even yield a number value, which means that get
is no longer invoked with function as an argument but with the result of function invocation.
In short, to pass a named function to another function, you don't specify its arguments. The supposed syntax that would allow this doesn't even make sense because it would be indistinguishable from a syntax of actual function invocation (i.e. the value of the call).
Upvotes: 1
Reputation: 707456
Any functions that you pass to app.get()
or app.use()
are automatically called with req, res, next
passed to them. That is how app.get()
and app.use()
are implemented.
To help you understand, this example:
app.get('/page', function(req, res){
console.log(req.params.foo);
});
is functionally the same as this:
app.get('/page', myHandler);
function myHandler(req, res) {
console.log(req.params.foo);
});
You do not want to do something like this:
app.get('/page', isLoggedIn(req, res), function(req, res){
// ...
});
because here you're attempting to execute isLoggedIn(req, res)
(when req
and res
are not yet defined) and then pass it's returned value to app.get()
. That is not what you want at all. You need to pass a function reference to app.get()
and it will supply the parameters when it calls the function. Any time you put ()
after a function in Javascript, that means you want to execute it NOW. But, if you just pass the function's name, then that is a function reference which can be stored and called later as desired.
This code example is analogous to this:
var result = isLoggedIn(req, res);
app.get('/page', result, function(req, res){
// ...
});
Besides the fact that this would cause an error because req
and res
are not defined at program start time when this would execute, hopefully you can see that you don't want to execute isLoggedIn()
now. Instead, you just want to pass a function reference so Express can call it later.
Upvotes: 4
Reputation: 15760
In this code
app.get('/page', isLoggedIn, function(req, res){
// ...
});
The app.get
method is being called with three arguments:
/page
Basically, this code is telling the express framework that when a GET
request is received for the /page
path, then it should call two functions: first, the middleware function and second the handler function.
The important thing to note here is that it is the framework doing the work. The framework is going to call the middleware function, then it's going to call the handler function.
Upvotes: 1