Reputation: 21
From client side (html), form is sent and server side decided which function to run by the one of the select option.
const decideWho = (form) => {
const choice = form.choice;
const obj = { key1 : 'func1(form.input1)',
key2 : 'func2(form.input2)'......};
return eval(obj[choice]||obj[default]);
}
Due to some other question, this code was put and Josh Wulf mentioned the danger of using eval.
So here I'm. I couldn't search related to my situation so if you know any answered question, let me know.
My problem is, at first I just put obj's value without quotation mark. Then the disaster happened. When the last line obj[choice]||obj[default] is called, all the functions in the obj are called and some functions were iterating repeatedly. I didn't know what went wrong.
Not only this.
const someFunc = () => {
const a = {
sourceFolder: "",
aFolder: "1OoK3j",
bFolder: "1M_cyv",
cFolder: "11maBJ",
dFolder: "1QxA8P",
eFolder: "11lG"};
for (let i in a)
eval(`var ${i} = getFolder(a['${i}']);`);
..move files to the destination above.
}
const getFolder = id => {
try {
if (id) {
return DriveApp.getFolderById(id);
} else return DriveApp.getRootFolder();
} catch (e) {
// If the folder by the id doesn't exists, return root folder.
return DriveApp.getRootFolder();
}
}
I didn't want to declare each folder using same function. So I put them in obj and without eval, iterated.
for (let i in a) var i = getFolder(a[i]);
Here again disaster. When I called aFolder expecting it would return the folder with the id mentioned, it iterates all the folders in the object.
Therefore, for the rescue, values are wrapped around with quotation mark and eval temporally.
What is supposed to be done here?
** Edited ** I'm trying to adopt function constructor.
const aa = form => `id: ${form.id}`;
const bb = () => "I'm b";
const aaa = form => {
const obj = {
key1 : 'aa(form)',
key2 : 'bb'
};
const handleIt = new Function('return ' + obj[form.choice])();
console.log(handleIt());
}
const cc = () => {
let form = {id: 'student 1', choice: 'key1'};
aaa(form);
form = {id: 'student 2', choice: 'key2'};
aaa(form);
}
These are simplified only to ask a question but real functions are long. When I perform
form = {id: 'student 2', choice: 'key2'};
aaa(form);
It works as expected. But when an argument is supposed to be passed, it says form is not defined.
let form = {id: 'student 1', choice: 'key1'};
aaa(form);
Where and how do I need to add the arguments if function constructor is the solution?
const aaa = form => {
const obj = {
key1 : 'aa(form)',
key2 : 'bb'
};
const handleIt = new Function('return ' + obj[form.choice])();
console.log(handleIt());
}
Edited 2 I got first one done without eval.
const decideWho = myForm => {
const obj = {
key1 : func1(myForm),
key2 : func2()
};
const handleIt = () => {return obj[myForm.choice];};
console.log(handleIt());
}
Upvotes: 0
Views: 153
Reputation: 21
Thanks to stackoverflow and people contributing, I got to solve my problem easily. Both my question was calling a function dynamically and first one was easier as @ymz 's suggestion.
const decideWho = (form) => {
const choice = form.choice;
const obj = { key1 : 'func1(form.input1)',
key2 : 'func2(form.input2)'......};
return eval(obj[choice]||obj[default]);
}
Is changed to
const decideWho = myForm => {
const obj = {
key1 : ()=> func1(myForm),
key2 : ()=> func2()
};
const handleIt = () => obj[`${myForm.choice}`]();
return handleIt();
}
And second one also similar but this time the assigning variable is dynamic too. That got solved too by the help of the comment from https://stackoverflow.com/a/28063322/12775761
for (let i in a)
eval(`var ${i} = getFolder(a['${i}']);`);
->
for (let i in a) this[`${i}`] = getFolder(a[i]);
If there is no evilness in "this", I'll use in this way. (This is server side function so I can't use window)
Upvotes: 0
Reputation: 6924
Well, he fact that you should't use eval
does not mean that you can't use new Function
instead. In fact, this question has a really good discussion about the differences between both
So.. maybe you should transform your code from
const decideWho = (form) => {
const choice = form.choice;
const obj = {
key1 : 'func1(form.input1)',
key2 : 'func2(form.input2)'
};
return eval(obj[choice]||obj[default]);
}
To something like:
const decideWho = (form) => {
const choice = form.choice;
const obj = {
key1 : 'return true',
key2 : 'return 7'
};
return new Function(obj[choice]||obj[default]);
}
Then just call your handler:
const funcHandler = decideWho(myForm)
funcHandler()
If you want to pass arguments as well, please refer to this MDN sample
Upvotes: 1