NodeJS Express Moongose route regex [duplicate] - express

This question inspired by this post but in my case I need to filter MongoId. Is it possible to make filtering easily that the below because I need use it in each route?
app.post('/:mongoId(^[0-9a-fA-F]{24}$)', function(req, res){
// Send query based on mongoId
}

You're almost there, just don't add the ^ and $ anchors. And the uppercase A-F range isn't even necessary since Express seems to match case-insensitive:
app.post('/:mongoId([0-9a-f]{24})', function(req, res){
var id = req.param('mongoId');
...
});

According to the Express API documentation, yes, you can use a regular expression as a path:
Regular expressions may also be used, and can be useful if you have
very specific restraints.
app.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){
var from = req.params[0];
var to = req.params[1] || 'HEAD';
res.send('commit range ' + from + '..' + to);
});

Related

Get selected url segment within Express

Is there a standard/predefined approach within Express to determine which url segment was used?
const countryCodes = ['us', 'uk', 'ie', 'au', 'ca'];
const cc = countryCodes.join('|'); // supported country codes
app.get(`/${cc}/verify`, (req, res, next) => {
// how to get specified cc value, from "us|uk|ie|au|ca" segment?
});
I can, of course, solve it with a head-on approach, by parsing the url, but I thought Express might have a more civilized approach to this already in place, I just cannot find it.

Apply multiple filters using the URL in KeystoneJS

I am just starting out with KeystoneJS. I have set up a section "items" and these have multiple relationships in it such as "manufacturer", "type", "category", etc.
While out of the box with Keystone you can filter by any one of these, I want to be able to filter by multiple params using the URL - e.g.
www.site.com/category/blinds/manufacturer/orion/
or
www.site.com/manufacturer/orion/type/venetian
Can anyone bump me in the right direction for how to accomplish this in keystone? Thanks.
app.get('/manufacturer/:manufact/category/:category/type/:type',function(req,res) {
var mymanufacturer= req.params.manufact;
var mycat= req.params.category;
var my type = req.params.type;
});
But the issue is that you must provide both category and type. So you can not use your 2nd url. for that you have to have categor like this.
www.site.com/manufacturer/orion/category/all/type/venetian
Instead You can use URL query like this
www.site.com?manufacturer=orion?category=blank&type= venetian
app.get('/', function(req, res) {
var mymanufacturer= req.query.manufacture;
var mycat= req.query.category;
var my type = req.query.type;
});

vars in express routes are blocking any following routes

I'm trying to use vars in my Express routes. They work fine but after i use a variable in a route, any routes after that one will not work. Here's really simple example.
/////////////////////////////////////////////planets
router.get('/:planetID', function(req, res, next) {
if(req.params.planetID == "hoth"){
res.render('index', {
title: 'Hoth',
subtitle:"Damn its cold"
});
}
});
////////////////////////////////////////////////jedi
router.get('/jedi', function(req, res, next) {
res.render('characters', {
title: 'Jedi',
subtitle:"why the f is this happening?",
});
});
In this example, the jedi route doesnt render anything. But if i put the jedi route before the planet route, everything works fine. Has anyone encountered this before?
Many thanks in advance for any help.
Express routes work in a pipe, that means that it will first check the first route and it will see that it accepts a parameter and it cannot see any difference between "/23423423" and '/jedi'. It assumes that jedi is an ID aswell. you should prefix it with
/planet/:planetID
for them not to conflict each other.
Express uses path-to-regexp for matching the route paths; see its documentation for all the possibilities in defining route paths. Apart from that, when you are working in express middle wares, do take care of the order of middle wares defined.
Note : Router is also a middleware in Express.
So you are working with two routes :
/:planetId
/jedi
If you define route /:planetId at the top then it actually treats /jedi as the same route with value of param planetId = jedi, whereas if you place your second route i.e.; /jedi at the top then it goes for exact match condition and if it find /jedi then only it executes the corresponding action else it will try with other routes defined.
ahh ok scopsy, now I see how your /23423423 example applies. Im sorry guys, I didnt post enough info I'm realizing. I had to use an if() statement to tell the route to move on if it didnt find a match. I did this using the next() function and a counter var.
router.get('/:planetID', function(req, res, next) {
var counter = 0;
planetJSON.planets.forEach(function(item){
counter++;
if(item.link == req.params.planetID){
planetDisplay.name = item.name;
planetDisplay.text = item.text;
planetDisplay.image = item.image;
res.render('index', {
planetGrab:planetDisplay,
planetList:planetJSON
});
}//end if()
else if(counter + 1 > planetJSON.planets.length){
next();
}
});//end for each()
});//end router.get
thanks again for your help

expressjs not passing req.params through middleware

Similar to this
I have the following route:
app.get('/blogpost/:link', middleware.loginCheck, blog.postBlogs);
Using req.params.link returns the link parameter.
When I ask for the req.params.link in middleware.loginCheck I receive an undefined.
It seems that req.params.link is not being passed through to the middleware because I can access it like so:
app.get('/blogpost/:link', function(req, res){console.log(req.params.link)});
Whats the problem with my middleware?
FINAL
a(href='/post/#{post.link}') #{comments} renders /post/myPostLink
{#post.link} only renders the variable substitute and does not add an extra /
a(href='/post#{post.link}') #{comments} renders '/postmyPostLink'
a(href='/post/' + post.link) #{comments} renders /post/myPostLink
So both #{post.link} or post.link work the same and req.params.link works on both calls.
UPDATE_2
I am using jade to render the web page. Inside there I have an anchor tag written as so: a(href='/post/#{post.link}) #{comments}
The achor tag works fine and directs me to the correct page. But express does not like this representation. Instead, if I change the anchor tag to a(href='/post/' + post.link) #{comments} req.params.link works fine.
UPDATE_1
req.param('link') works for this case.
There is no problem with the middleware.
But why wouldn't req.params.link work?
OK, we went back and forth in the comments a bit, but now my guess is that the problem is double slashes in your URL
a(href='/post/#{post.link}') #{comments}
That is A) missing a closing quote, but I assume that is a typo just in your question here, not in your code. and B) the real problem is that post.link includes a leading slash, so you end up with this HTML:
<a href='/post//post_link_name'>42</a>
Thus express is parsing that as an empty :link parameter. Change your jade to this:
a(href='/post#{post.link}') #{comments}
and you should get back in business.
In recent versions of express you can use router.param() as your middleware to specifically work on the req.params:
var router = express.Router();
router.param( "nickname", function (req, res, next, nickname) {
console.log( "nickname: ", nickname );
next();
});
router.get( "/user/:nickname", myController.method );
what does the signature of middleware.loginCheck look like? It needs to return a function(req, res, next)

Making a REST API: How do I route a filepath using express for node

var express = require('express');
var app = express();
app.get('/files/:service/:op/:file', function(req, res){
console.log(req.params.file)
})
app.listen(3000);
Calling http://localhost:3000/files/farm/get/chicken will log chicken.
Calling http://localhost:3000/files/farm/get/barn/yard/chicken will log barn.
How can I make an Express app.VERB(path, callback) path log barn/yard/chicken?
Change your route to something like this:
app.get('/files/:service/:op/*', function(req, res){
console.dir(req.params);
console.log(req.params[0]); // this is what you want
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('OK');
});
Notice how the last parameter was changed to an * so that it takes single values (like chicken) or multi-values (like barn/yard/chicken). The issue here is that the slash character is used to split the URL components but you want to sometimes split the values but not others. The * will automatically lump the last set of values (1 or many) into a single element.
See http://expressjs.com/api.html#req.params
Try this:
console.log(req.params.service + "/" + req.params.op + "/" + req.params.file);