Answer the question
In order to leave comments, you need to log in
How to get the name of an Express route parameter?
How can I get the parameter name in an Express route?
For example, I have a route '/user/:userId'
When I go, I get a dynamic address /user/5af2fe6cc7a7631ae040db43
. I want to make an intermediate handler that will select information about the route from the database.
Finding a dynamic address in the database will not work without converting 5af2fe6cc7a7631ae040db43
to /:
and searching for a match /user/:
. I made such a script, but I wonder if there is an easier way, especially that the script works with only 1 parameter, that is, for example /user/:username/:userId
, it will not be able to process it yet (it needs to be finished).
Sample code for clarity:
// Moongose
var Routes = mongoose.model('Routes', RoutesSchema);
app.use((req, res, next) => {
//Получаем информацию о маршруте из бд
Routes.find({'path' : req.originalUrl}, (err, pageInfo) => {
// Если документ не найден
if(pageInfo == null) {
var search = req.originalUrl.split('/');
search.splice(-1,1,':');
search = search.join('/');
// serach = /user/:
Routes.findOne({'path' : {$regex: search}}, function(err, pageInfo) {
// Устанавливаем локальные переменные ответа
res.locals.title = pageInfo.title;
res.locals.description = pageInfo.description;
next()
})
}
// Если все ок
else {
// Устанавливаем локальные переменные ответа
res.locals.title = pageInfo.title
res.locals.description= pageInfo.description
next()
}
})
})
Answer the question
In order to leave comments, you need to log in
In short, the question is simple without a bullshit.
Here is a piece of code taken from a case in expressjs and their docks.
The bottom line is that before starting the server, it passes through the handlers and inserts the front springboard.
const express = require('express')
const app = express()
app.get('/path/:id', function(req, res, next) {
res.send(`${this.method} ${this.path}`)
})
function print (path, layer) {
if (layer.route) {
layer.route.stack.forEach(print.bind(null, path.concat(split(layer.route.path))))
} else if (layer.name === 'router' && layer.handle.stack) {
layer.handle.stack.forEach(print.bind(null, path.concat(split(layer.regexp))))
} else if (layer.method) {
console.log('%s /%s',
layer.method.toUpperCase(),
path.concat(split(layer.regexp)).filter(Boolean).join('/'))
//
// Аттачим хэндлеру this :D
//
const m = layer.method.toUpperCase()
const p = path.concat(split(layer.regexp)).filter(Boolean).join('/')
const fn = layer.handle
layer.handle = function trampoline() {
const self = {
method: m,
path: p
}
fn.apply(self, arguments)
}
}
}
function split (thing) {
if (typeof thing === 'string') {
return thing.split('/')
} else if (thing.fast_slash) {
return ''
} else {
var match = thing.toString()
.replace('\\/?', '')
.replace('(?=\\/|$)', '$')
.match(/^\/\^((?:\\[.*+?^${}()|[\]\\\/]|[^.*+?^${}()|[\]\\\/])*)\$\//)
return match
? match[1].replace(/\\(.)/g, '$1').split('/')
: '<complex:' + thing.toString() + '>'
}
}
app._router.stack.forEach(print.bind(null, []))
app.listen(3000, () => console.log('Example app listening on port 3000!'))
It will not work to get the name of the request parameter, since the intermediate handler is executed before processing the route itself and is not aware that 5af2fe6cc7a7631ae040db43
this is a request parameter.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question