Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot get request params in express middleware

I am not able to read any req.params in my middleware. I have a minimal express web server that looks like

'use strict';

var express = require('express');
var app = express();

//middleware
function userMiddleware(req, res, next) {
  console.log('user came in. Hello ' + req.param('name'));
  next();
}

//register middleware
app.use('/user', userMiddleware)

// routes
app.get('/user/:name', function(req, res) {
  res.send('username : ' + req.params.name);
});

app.listen(3000);
console.log("listening on 3000...");

When I try to hit localhost:3000/user/williams , I expect to see in the log :

user came in. Hello williams

but I see

user came in. Hello undefined

Should I include any other middleware so that the req.params is populated in the middleware ? I'm using [email protected]

like image 651
gprasant Avatar asked Aug 15 '14 00:08

gprasant


People also ask

What is request params in Express?

The req. params property is an object that contains the properties which are mapped to the named route "parameters". For example, if you have a route as /api/:name, then the "name" property is available as req.params.name. The default value of this object is {}.

How does Middlewares work in Express?

Middleware functions are functions that have access to the request object ( req ), the response object ( res ), and the next function in the application's request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.

How many Middlewares you can use in Express?

We can use more than one middleware on an Express app instance, which means that we can use more than one middleware inside app. use() or app. METHOD() .

Which is the correct format to get variables in Express JS using get () method?

method == 'GET') { var url_parts = url. parse(request. url,true); //console.


2 Answers

I think app.param() is unconventional in this case and not really intuitive. Since I already had the function representing the middleware, I could do :

//middleware
function userMiddleware(req, res, next) {
  console.log('user came in. Hello ' + req.params.name);
  next();
}

// routes
app.get('/user/:name', userMiddleware, function(req, res) {
  res.send('username : ' + req.params.name);
});
like image 61
gprasant Avatar answered Nov 16 '22 03:11

gprasant


EDIT

My answer below is incorrect. You don't actually need json or urlencoded middleware to get route params - they're only needed for req.query and req.body to work. As you're aware (since you're one of the posters there), the link you provided in your comment describes the issue:

https://github.com/strongloop/express/issues/2088

The problem is that you are trying to access route parameters before they exist - middleware runs before routes do. One solution would be to use app.param() as suggested in that link (instead of your userMiddleware):

app.param('name', function(req, res, next, name) {
    console.log('user came in. Hello ' + name);
    next();
});

Note that this will find name parameters in ALL routes so you might want to name the parameter something a bit more specific, like username. You could also check the beginning of req.url if you wanted to narrow it down that way.

BTW Using req.param() as you did in your original code should generally be avoided; to quote from the Express docs: Direct access to req.body, req.params, and req.query should be favoured for clarity - unless you truly accept input from each object.


OLD ANSWER

Leaving it here since it contains info that might be useful in other situations...

I believe you need to add this middleware in order to have GET and POST variables available:

.use(express.json()) //support JSON-encoded bodies
.use(express.urlencoded()) //support URL-encoded bodies

And:

.use(express.methodOverride())

If you also have a need for HTTP verbs such as PUT or DELETE in all browsers.

Instead of json and urlencoded, you could just use bodyparser, but that would be a security vulnerability due to file uploads. See http://andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html. Also, bodyparser is deprecated in Express 4. Note that if you want to support file uploads you'll need to use additional middleware for that (a good option is https://www.npmjs.org/package/multer).

like image 27
Matt Browne Avatar answered Nov 16 '22 03:11

Matt Browne