I have an object which returns,
[
{
name:"getSpeed",
params:["distance","time"]
},
{
name:"getTime",
params:["speed","distance"]
},
...
]
This object is subject to change as it is gathered from an embedded device.
im trying to convert this into an object with callable functions i.e.
let myObj = {
getSpeed: function(distance, time){
/* do something (this is irrelevant) */
},
getTime: function(speed, distance){
/* do something (again not relevant) */
}
}
is there any way to map an array of strings to function parameters when mapping over an array?
CodePudding user response:
According to your comments it appears you want to create functions from this definition which send commands with a function-call-like string which is eval
ed on the other side, and you don't actually care about the paramater names but rather about the correct number of parameters.
I would therefore recommend something like this:
const myObj = Object.fromEntries(data.map(({ name, params }) => [
name,
(...args) => {
if (args.length !== params.length) {
throw new TypeError(`${name} expected ${params.length} arguments, got ${args.length}`)
}
this.UART.write(`${name}(${args.map(arg => JSON.stringify(arg)).join(',')})`)
}
]))
This will work with all the datatypes that JSON supports, and will as a side effect also pass undefined
as argument correctly.
Here is a runnable example with console.log
instead of this.UART.write
:
const data = [
{
name: "getSpeed",
params: ["distance", "time"]
},
{
name: "getTime",
params: ["speed", "distance"]
}
]
const myObj = Object.fromEntries(data.map(({ name, params }) => [
name,
(...args) => {
if (args.length !== params.length) {
throw new TypeError(`${name} expected ${params.length} arguments, got ${args.length}`)
}
console.log(`${name}(${args.map(arg => JSON.stringify(arg)).join(',')})`)
}
]))
myObj.getSpeed(123, 456) // prints `getSpeed(123,456)`
myObj.getTime(123, 456) // prints `getTime(123,456)`
myObj.getTime("hello", true) // prints `getTime("hello",true)`
myObj.getTime(1) // throws `getTime expected 2 arguments, got 1`
However, as you said yourself, the whole eval
business is not ideal anyway. I would recommend - if possible - to reconsider the protocol to use something more secure and robust like gRPC or, one layer below, protocol buffers. Given that you are using JavaScript on both ends, JSON-RPC could also be a nice solution.