How to use parameters containing a slash character? - javascript

My MongoDB keys in person collection are like this:
TWITTER/12345678
GOOGLE/34567890
TWITTER/45678901
...
I define getPersonByKey route this way:
router.route('/getPersonByKey/:providerKey/:personKey').
get(function(req, res) { // get person by key
var key = req.params.providerKey + '/' + req.params.personKey;
// ...
}
);
Of course I'd prefer to be able to write something like this:
router.route('/getPersonByKey/:key').
get(function(req, res) { // get person by key
var key = req.params.key;
// ...
}
);
But this doesn't work, since GET http://localhost/getPersonByKey/TWITTER/12345678 of course results in a 404, since the parameter with the slash is interpreted as two distinct parameters...
Any idea?

Express internally uses path-to-regexp to do path matching.
As explained in the documentation, you can use a "Custom Match Parameter" by adding a regular expression wrapped in parenthesis after the parameter itself.
You can use the following path to get the result you need:
router.route('/getPersonByKey/:key([^/]+/[^/]+)').
get(function(req, res) { // get person by key
var key = req.params.key;
// ...
}
);
You can test and validate this or any other route here.

You can use this if your parameters has containing slashes in it
app.get('/getPersonByKey/:key(*)', function(req, res) { ... })
It works for me (at least in Express 4). In my case, I used parameters like ABC1/12345/6789(10).
Hopefully this useful.

app.get('/getPersonByKey/:key(*)', function(req, res) { ... })
This isn't working for me.
Swagger-ui will encode the path var before using it.
e.g. article/2159 will become article%2F2159.
When going directly with curl, it will not get encoded. the slash will remain a slash instead of %2F. And then the route is not matched.
Update: I'm on fastify. On express 4.X this works correctly.

Related

Object of which I have a working method for is somehow undefined? Javascript app.patch request [duplicate]

I am trying to create two routes in my express app. One route, without a parameter will give me a list of choices, the other one with a parameter will give me the choice related to the id.
router.get('/api/choice', choice_controller.get_choices);
router.get('/api/choice/:id', choice_controller.get_choice);
When I go to .../api/choice/?id=1 the api returns the list of choices, and therefore follows the route without the param (/api/choice). How do I make sure that the router does not omit the parameter?
Thanks in advance.
UPDATE
It seems that it does not fire the /api/choice/:id route. If I remove the one without the param, it gives a 404 so. Could someone explain to me why /api/choice/?id=1 is not getting picked up by /api/choice/:id?
Basically, your declared routes are documented in the Express documentation.
The second route is resolved by a URL like /api/choice/hello where 'hello' is mapped into the req object object as:
router.get('/api/choice/:id', function (req, res) {
console.log("choice id is " + req.params.id);
});
What you are actually trying is mapping query parameters.
A URL like /api/choice/?id=1 is resolved by the first router you provided.
Query parameters are easy to get mapped against the request as:
router.get('/api/choice', function (req, res) {
console.log('id: ' + req.query.id);
//get the whole query as!
const queryStuff = JSON.stringify(req.query);
console.log(queryStuff)
});

How can I get the hexadecimal numbers from the base URL string

I am doing codes in node js express js But while working, I thought that if the hexadecimal number was taken from the base URL string, then my work would be easier.
I mean:
baseUrl: '/api/v1/movies/61b6e1c5503b122ff9436b14/seasons' (Get from req.baseUrl)
My base URL string is: '/api/v1/movies/61b6e1c5503b122ff9436b14/seasons'
I need just: 61b6e1c5503b122ff9436b14
I am currently using the javaScript replace() method but it does not seem to be very effective to me. I am especially interested to know any good method.
Thanks
Regexp would be useful unless you are looking for dynamic routes
This would get the code
let baseUrl = '/api/v1/movies/61b6e1c5503b122ff9436b14/seasons'
const hex = baseUrl.match(/movies\/(\w+)\/seasons/)[1]
console.log(hex.toUpperCase());
What you're looking for are called dynamic routes and in express you can do like this:
const express = require('express');
const app = express();
app.get('/api/v1/movies/:hexid/seasons', (req,res) => {
console.log(req.params.hexid);
})
You can find more info in their docs ( search for :bookId )
You can use req.params to map the route parameters in ExpressJS
app.get('/api/v1/movies/:hashid/seasons', function (req, res) {
console.log(req.params.hashid)
})

Specific URL path

I'm looking for a method to catch these urls:
https://my.server.com/subsite
https://my.server.com/subsite.html
... but not these:
https://my.server.com/otherpath/subsite
https://my.server.com/other/path/subsite
What I got so far is this code - but obviously I'm also catching the urls I do not want to get (from above):
var express = require('express');
let app = express();
app.get(/\/subsite(?:\.html)?$/, function(req, res) {
})
I tried to fix my code by inserting com before the regex but this does not seems to be a working solution: /.*com\/subsite(?:\.html)?$/.
How can I get around this issue?
This worked for me.
app.get(/.*com\/subsite(?:\.html)?$/, function(req, res) {
})
Here is where i tested it: https://regex101.com/r/42lhKg/1
You don't need to use a Reg Ex object, this will work fine:
app.get("/subsite(.html)?", function(req, res) {
/*...*/
})
Matches any path beginning with "subsite" and with possibility of a .html
Your Regex is missing a the constraint to make subsite appear only in the begging ^:
/^\/subsite(?:\.html)?$/
witch is the same as using just the string:
"/subsite(.html)?"
that I mentioned in the other answer.
Don't forget that in express you only care about the path and query part of the url.

how to pass a url as a "url parameter" in express?

In my express app I have a router listening to api/shorten/:
router.get('api/shorten/:longUrl', function(req, res, next) {
console.log(req.params.longUrl);
}
When I use something like:
http://localhost:3000/api/shorten/www.udemy.com
I get www.udemy.com which is what I expect.
But when I use:
http://localhost:3000/api/shorten/http://www.udemy.com
I get a 404 error.
I want to get http://www.udemy.com when I access req.params.parameter.
I'm not sure if you're still looking for a solution to this problem. Perhaps just in case someone else is trying to figure out the same thing, this is a simple solution to your problem:
app.get('/new/*', function(req, res) {
// Grab params that are attached on the end of the /new/ route
var url = req.params[0];
This way you don't have to sweat about any forward slashes being mistaken for routes or directories, it will grab everything after /new/.
You need to use encodeURIComponent in the client, and decodeURIComponent in the express server, this will encode all the not allowed characters from the url parameter like : and /
You need to escape as so:
escape("http://www.google.com")
Which returns:
"http%3A//www.google.com"
I just want to add that if you pass another params like ?param=some_param into your "url paramter" it will not show up in req.params[0].
Instead you can just use req.url property.

adding a query string to an URL

I'm working on a app in Node/Express/Jade environment.
Let's assume I start my app, and direct my browser to this URL:
/superadmin/?year=2012
On this page, i find a list with object, sorted in a default order. Here is also a link that will re-sort the list objects in another order. I jade this link look like:
a(href = '?sortAfter=company&ascending=1') Company
If i press this link, I will get the items sorted in the way I want, but the ?year=2012 from earlier query string will be lost.
Question: How do I re-write this link to add the new query strings, and not replace it.
Got the same problem, here's how I fixed it:
Installed https://npmjs.org/package/URIjs via npm install URIjs
Now, in your route :
var URI = require('URIjs');
app.get('/', function(req, res) {;
res.render('views/index.jade', {
urlHelper: function (key, value) {
return (new URI(req.url)).setQuery(key, value);
}
});
};
And in jade :
a(href=linkHelper('acesnding',1)) Company
I've come up with my own npm package for just this cause -> https://www.npmjs.com/package/qsm
Example:
var qsm = require('qsm');
app.get('/', (req, res) => {
res.render('views/index.jade', {
addQueryString: (key, value) => {
return qsm.add(window.location.href, [{ query: key, value }]);
}
});
});
and in jade
a(href= addQueryString('acesnding',1)) Company
Please refer the README in qsm and you'll see how easy it is to append querystring, remove specific querystrings and even parse and much more!
You can even clear, remove and replace querystrings. The best of all, it doesn't have to be a URL, it can be whatever string you can think of, but it will behave as that string is an url and append querystring to it: e.g: ?key=value or &key=value depending on what is already present.

Categories