-1

I'm trying to convert a string into a function without using eval(), however whenever I pass the function name into the window object and check its type. Javascript does not seem to recognize it as a function. I always get this custom error message I've defined in the else statement: "Could not find function: 1->validateLogin".

My dom_ready prototype:

dom_ready: function (inputFunc) {
    document.addEventListener("DOMContentLoaded", function () {
        try {
            inputFunc();
        } catch (e) {
            DN.errors.push(e.message);
        }
    });
},

function show_pass() {
    ...

}

function validateLogin(k) {
   ...
}
DN.DOM.dom_ready(function () {
var event_ids = [
    ["#login-form-dialog", "validateLogin", "submit", 1]
    ["#loginnotes", "validateLogin", "click", 1],
    ["#loginnotes2", "validateLogin", "click", 2],
    ["#show-pass", "show_pass", "click", ""],
]

for (var i = 0; i < event_ids.length - 1; i++) {

    var fN = window[event_ids[i][1]];


    if (typeof fN === 'function') {

        $(event_ids[i][0]).on(event_ids[i][2], function () {
            fN(event_ids[i][3]);
        })

    } else {
        console.log("Could not find function: " + i + "->" + event_ids[i][1]);
    }
}
});
David Yue
  • 713
  • 7
  • 24

2 Answers2

1

The particular syntax error causing your problems was addressed in other answers. To find such syntax errors, look at the console for errors. Or, run your code through a linter. Otherwise, you will have to post to SO every time you forget a comma, which does not seem to be a very scalable approach.

More basically, do not pass around function references using strings giving their names, which you need to then look up on the window object. Instead, just pass the function reference itself (validateLogin). Unlike some other languages, in JS functions are first-class citizens which can be referred to and passed around as themselves. Your code would look like this:

DN.DOM.dom_ready(function () {
  var event_ids = [
    ["#login-form-dialog", validateLogin, "submit", 1]
                           ^^^^^^^^^^^^^
  ...

  for (var i = 0; i < event_ids.length - 1; i++) {
    var fN = event_ids[i][1];

Of course, you will have to make sure that validateLogin is visible at the time this ready function is executed.

However, you have a more basic problem which will prevent your code from running properly, in the following lines:

$(event_ids[i][0]).on(event_ids[i][2], function () {
  fN(event_ids[i][3]);
})

Here, the anonymous function is a closure over the variable i, and at the time it is executed (when the event occurs), i will already be at its maximum value of 3. There are many questions and answers on this topic here on SO, but the easiest solution is to use for (let i, if you are working in an environment that supports let. Otherwise, see questions like this one.

Community
  • 1
  • 1
0

You are missing a comma after the first item in event_ids:

var event_ids = [
    ["#login-form-dialog", "validateLogin", "submit", 1], // <-- missing comma
    ["#loginnotes", "validateLogin", "click", 1],
    ["#loginnotes2", "validateLogin", "click", 2],
    ["#show-pass", "show_pass", "click", ""],
]; // <-- also it is better practice to have semi-colon here
yas
  • 3,520
  • 4
  • 25
  • 38
  • Thank you. Time to pay a bit more attention. – David Yue Mar 19 '16 at 04:19
  • At this stage, I can't believe anyone uses an IDE that doesn't catch missing commas. I've used WebStorm (costs money), Sublime Text (free to try, but you can use indefinitely without paying money), and Atom (free but occasionally buggy). – Andrew Mar 19 '16 at 04:22
  • If the problem is a typo, then vote to close as a typo, possibly leaving a comment. Or, if you really want to give an answer, give one that explains to the OP how to find his own typos, since he hardly can come to SO every time he forgets a comma. –  Mar 19 '16 at 05:11
  • This would prevent his program from running, but it would not account for him getting the error message he reports. –  Mar 19 '16 at 05:29