Reputation: 1714
Hi have the following simple ExpressJS application, where the routes are dynamically created based on a configuration. I am having a hard time trying to pass in a bunch of parameters to the handler so that the values are returned in the respective controller.
const express = require('express');
module.exports = class App {
get routes() {
return [
{
path: '/',
verb: 'get',
method: 'home',
params: ['req.query.ref', 'req.query.country'],
},
];
}
constructor() {
this.app = express();
this.register();
}
register() {
const { routes } = this;
routes.forEach((route) => {
const {
path, verb, method, params,
} = route;
// if you replace the params with [req.query.ref, req.query.country] it will work as expected
this.app[verb](path, this.handler(this[method].bind(this), (req, res, next) => params));
});
}
handler(promise, params) {
return async (req, res, next) => {
const bound = params ? params(req, res, next) : [];
console.log(bound);
try {
const result = await promise(...bound);
res.json(result);
} catch (err) {
throw err;
}
};
}
home(payload) {
console.log(payload);
return Promise.resolve({ status: 'OK' });
}
};
Upvotes: 3
Views: 184
Reputation: 3111
Maybe you can take a look to the arguments object. All functions have this object and it contains an array with all arguments received in the function. I think it could be what you are looking for.
JavaScript functions have a built-in object called the arguments object.
The argument object contains an array of the arguments used when the function was called (invoked).
This way you can simply use a function to find (for instance) the highest value in a list of numbers:
This is an example how it works:
x = findMax(1, 123, 500, 115, 44, 88);
function findMax() {
var i;
var max = -Infinity;
for (i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
More info: https://www.w3schools.com/js/js_function_parameters.asp
Upvotes: 1
Reputation: 3264
well you can build the query if with split if your params has the same format
--update--
this solution is based on req or res with x params for each
const express = require('express');
module.exports = class App {
get routes() {
return [
{
path: '/',
verb: 'get',
method: 'home',
params: ['req.query.ref', 'req.query.country'], //changed
},
];
}
constructor() {
this.app = express();
this.register();
}
register() {
const { routes } = this;
routes.forEach((route) => {
let {
path, verb, method, params,
} = route;
this.app[verb](path, this.handler(this[method].bind(this), (req, res, next) => this. paramsStringToArrayValues(req, res,params))
}));
});
}
paramsStringToArrayValues(req, res,params){
return params.map(param => {
let paramArr = param.split('.');
let obj = paramArr.shift() === 'req'? req : res
paramArr.forEach(key =>{
obj = obj[key]
})
return obj
})
}
handler(promise, params) {
return async (req, res, next) => {
const bound = params ? params(req, res, next) : [];
console.log(bound);
try {
const result = await promise(...bound);
res.json(result);
} catch (err) {
throw err;
}
};
}
home(payload) {
console.log(payload);
return Promise.resolve({ status: 'OK' });
}
};
Upvotes: 0
Reputation: 25319
Most of your issues stem from the structure of your route definition. It would make more sense to create direct references to the things you want to use, not noting function references etc down as strings.
get routes() {
return [{
path: '/',
method: this.get,
endpoint: this.home,
paramMap: req => [req.query.ref, req.query.country],
}];
}
Once you make the appropriate changes elsewhere, you no longer have the original problem you described.
Upvotes: 1