express.js: capture generic routes with numeric Id - javascript

I'm trying to define a generic handler for express.js routes
the idea is to get something like
get /api/xxx/yyy -> get all data
get /api/xxx/yyy/11-> get record 11
I need to capture xxx/yyy on one variable and 11 in another
this works fine:
app.get('/api/*', function(req, res, next) {
I'm not capturing anything, but I read it with the req.path property
But I can't seem to solve this:
app.get('/api/*/:id(\\d+)$', function(req, res, next) {
If I try with:
http://localhost:3000/api/clientes/2
this is what I get in req.params:
req.params = [ '2', id: 'clientes' ]
It seems like the path get binded to id, and the id is unbound to any variable.
moreover, if I try fetching this:
http://localhost:3000/api/clientes/nuevos/2
The route doesn't match
So, I'm looking for a regexp that allow me to catch several paths (xxx/yyy) and also the last one if it's a number (11)

I could solve it using a regular expression instead of a string:
app.get(/\/api\/(.*)\/(\d+)/, function(req, res, next) {
Now if I try with
http://localhost:3000/api/clientes/menores/71
I get
req.params = [ 'clientes/menores', '71' ]
But I'd like to know if there's some way to use the :id marker...

Related

How to expect a specific word after a route parameter in Node.js?

Currently I have this route:
router.get('/:board/:threadId', function(req, res, next) {
// doing stuff
});
So the users go to /a/1 and it triggers this route with board = a and threadId = 1.
What I want now is that the users need to go to /a/1.html to trigger this route (but threadId should still equal 1. How do I add the .html in that route? I tried /:board/:threadId.*.html$ after reading the express documentation but it's not working as expected.
The hyphen (-) and the dot (.) are interpreted literally by string-based paths.
Did you try this?
router.get('/:board/:threadId.html', function(req, res, next) {
// doing stuff
});

How to get appended URL value? (e.g. localhost:3000/URL)

I'm trying to use other URL to be used as a data in my app.
For example, If I visit localhost:3000/https://www.google.com/robots.txt
Then I would like to get https://www.google.com/robots.txt as a parameter so I can use it.
I tried the following approach but it only works if the trailing value has no slash.
app.get('/:id', function (req, res) {
res.send(req.params)
})
Is there a possible way to get the appended URL?
You can use /* to grab the Parameters and then get the index 0 to get the exact URL
app.get('/*', function(req, res) {
var url = req.params[0];
res.send(url);
});

How to use ? as separator in webservice url

using nodejs / express, i'm trying to make a webservice using ? to separate url from parameters and then & as parameters separators.
when using this, it works
app.get("/tableref/:event/:queryObject", function(req, res) {})
or this one works also
app.get("/tableref:event&:queryObject", function(req, res) {})
but not this, I got 404 error:
app.get("/tableref?:event&:queryObject", function(req, res) {})
It seems that it is the ? that is the problem. Is there a way to authorize it? escape it?
I'd like to use express validator like this
Thanks
To get value from query string you don't need to specify those query string parameters in Express routes.
Your code should look like this
app.get("/tableref", function(req, res) {
res.json(req.query)
});
when you enter the URL localhost/tableref?hello&world you will get the response {"hello": "", "world": ""}
and if you want to pass data to query string variables, you can also enter the URL localhost/tableref?hello=world&foo=bar and you will get the response {"hello": "world", "foo": "bar"}

Is this the right behavior to expect from the new Express 4 Router?

I have recently started a new app with Express 4.0, and I really liked the new express.Router() thing.
Something that got me stuck for quite some time was the following behavior:
var app = require('express')(),
router = express.Router();
router.get('/me', function(req, res, next) {
if(someBoolean) {
return next(); //here I expect to get a 404 error from express!
}
res.json({name: 'yourName'});
});
router.get('/:user_id', function() {
//any code here!
});
app.use('/users', router);
I always used next() (in Express 3.x) to either call the next middleware or to force a 404 from the server.
Since /users/me and /users/45 are totally different routes and are not mounted in a way that one should come after another, I wonder why I get code in /users/:user_id evaluated after calling next() in /users/me.
Am I doing something wrong or things are supposed to work different in Express 4.0?
This is working as expected. In Express 4 all middleware/routes are executed in the order that they are added to your app, so the path for your second router.get() is tested and matches because :user_id could be any kind of token, numeric or otherwise (basically any character that isn't /).
You can fix this at least in a couple of different ways:
Don't call next() in your first router.get()
Use a RegExp instead of a string to ensure that user_id only matches a numeric value. For example: router.get(/^\/(\d+)$/, function() {. However then you have to access the param via regexp group index instead of by a name: var user_id = req.params[0].

Express middleware not having an effect

I have the following code:
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.use(express.cookieParser());
var port = Number(process.env.PORT || 5000);
app.get('/test/:id', function(req, res) {
res.send(req.params);
});
app.listen(port);
console.log("Listening on port " + port);
When I hit http://localhost:5000/test/12345 in my browser, I see:
[]
But I'm expecting to see the populated req.params object with id: 12345. Any idea what I'm doing wrong?
Thanks.
Checked and saw that req.params is actually an associative array, which is almost similar to object but not quite. Not sure why express defined it as such. The only benefit it gets is the added length property for an array. And res.send will try to JSON.stringify your output, which in turn will see that it's an array and only take care of indexes which are numeric. Hence the empty [] as return value.
You can validate this by doing -
var myParams = {};
Object.keys(req.params).forEach(function(key){
myParams[key] = req.params[key];
});
res.send(myParams);
You can also see that JSON.stringify only cares about numeric index by defining your route as such -
app.get('/test/:0', function(req, res) {
res.send(req.params);
});
The response object will be named after your id. If you check it in your browser's traffic you can see a file called 12345. Though you can check that your server gets the id by logging it on the server side.
app.get('/test/:id', function(req, res) {
console.log(req.params);
res.send(req.params);
});
If you want to pass variables to a view you might want to use the res.render(...) function where you can pass in arguments.
To get the 123451 send the res.send(req.params.id);.
The reason why you are not getting anything using res.send(req.params) is because req.params is an instance of Array and default mechanism tries to covet an array into string which is giving you [].
What you could do to see all params is as follows:
app.get('/test/:id', function(req, res) {
res.send(require('util').inspect(req.params));
});
That will give you output like (using this URL http://localhost:5000/test/12345):
[ id: '12345' ]
That approach will also work with routes having more parameters e.g. the following code snippet and that request http://localhost:5000/test/name/234
app.get('/test/:name/:id', function(req, res) {
res.send(require('util').inspect(req.params));
});
will give you:
[ name: 'name', id: '234' ]
Alternatively, if you would like to get JSON formatted output of a JavaScript object, you can use res.json. But note that json will also generate [] if you perform res.json(req.params) as it will render req.params array in a standard way.
I hope that will help.
Note that as of 9th April 2014 (Express version 4.0.0) req.params is an object instead of an array so you should not have similar issues with v4.0.0 and your code should work as expected.
app.get('/test/:id', function(req, res) {
res.send(req.params);
});
The problem isn't your middleware. Neither bodyParser nor cookieParser provide the named url parameter parsing. That being said, your code looks correct to me. Are you absolutely certain you restarted your node server after making the code change?

Categories

Resources