0

i want to create a dynamic generated form using javascript, everything works fine, until i try to pass an array as parameter. When i do this, an error happens. Coulr anyone explain what this is?

Heres my code:

var loadFrm = function(component) {
    for(nItem in component) {
        var myComponent = "add" + firstToUpper(component[nItem].type);
    var callComponent = myComponent + "(" + component[nItem].opt + ");";
    eval(callComponent);
    }
}

var json = [
    {
        type: "scale",
        opt: {content: [{label: "male", value: "m"}, {label: "female", value: "f"}]}
    }
];

loadFrm(json);

Edit Here's the error:

missing ] after element list
[Break on this error] addScale([object Object]);
0

2 Answers 2

5

If you use a debugger to look at the string callComponent, you'll probably find it looks something like this:

addScale([object Object])

...which isn't what you want. That's because you're effectively calling toString on your opt object, and the default toString on objects just looks like that. The eval error is because that's invalid syntax.

Generally speaking, any time you think you need to use eval, there's almost certainly a better answer. In this case, it looks like you're trying to call a function and pass in opt. Assuming these functions are "globals", you can do that like this:

var loadFrm = function(component) {
    var nItem, functionName;

    for (nItem = 0; nItem < component.length; ++nItem) {
        functionName = "add" + firstToUpper(component[nItem].type);
        window[functionName](component[nItem].opt);
    }
}

Live example

Notes on the above:

  1. Don't use for..in to loop through arrays unless you really know what you're doing. for..in does not enumerate the indexes of an array, it enumerates the properties of an object.
  2. We look up the function by name using window[functionName]. This works because "globals" are actually properties of the window object, and you can look up properties using a string name for them using bracketed notation.
  3. Having gotten the function via window[functionName], we just call it directly, passing in the object opt rather than a string form of it. I assume addScale expects to see an object.
  4. I moved all of the vars to the top of the function because that's where they really are (details).
  5. If you can, I'd recommend moving addScale and the related functions to their own object rather than putting them on window. The window namespace is already pretty crowded. Here's the live example modified to not add any symbols to window at all, instead putting the addScale function on an object called functions and using it from there.

Off-topic: The syntax var loadFrm = function(component) creates an anonymous function that it then assigns to a variable. This is used a lot, but unless you're creating different functions based on a condition, e.g.:

var f;
if (...) {
    f = function() { ... };
}
else {
    f = function() { ... };
}

...it's not actually useful. (If you are creating different functions based on a condition like that, then it's not only useful, it's necessary.) I recommend using named functions whenever possible, because a function with a name helps your tools help you by showing you the function name in error messages, call stacks, etc.

Off-topic 2: You have a variable called json, but FYI, it's not using JSON notation. It's using a combination of JavaScript array and object literal notation, which is a superset of JSON. You'll see a lot of people confused about this, I mention it because you said you're new and so it's worth nipping in the bud. :-) JSON is purely a notation. (A very useful one.)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the suggestion. Could you write a demo code for a possible solution? Im a newbie and i have not a big vision for solutions in JS.
@Nort: That is the code for the solution. I'll throw together a live example, one sec.
-1

Use this:

fn = eval(functionName);
fn(objParameter)

1 Comment

Please explain your answer?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.