0

I am trying test out in javascript can dynamically call a method and dynamically set parameters for it.

let obj = {
  method: 'foo1',
  params: ['one', 'two']
}

foo 1(p1, p2) {
 // do something
}

To run it =>

[obj.method](obj.params)

Is there any way to dynamically add params from an array.

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
menaka
  • 1,045
  • 1
  • 12
  • 30
  • 1
    You're looking for either `.call` or `.apply` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply `obj.method.call(obj.method, obj.params);` – briosheje Jun 28 '19 at 13:29
  • Possible duplicate of [Calling dynamic function with dynamic parameters in Javascript](https://stackoverflow.com/questions/676721/calling-dynamic-function-with-dynamic-parameters-in-javascript) – Liam Jun 28 '19 at 13:49
  • @briosheje I don't think you understood the question. `obj.method` isn't going to work because that is a string and you can't use `call` or `apply` or `bind` on a string. – Scott Marcus Jun 28 '19 at 13:55
  • @ScottMarcus wops, you're right, you need to invoke through `window`, unless it belongs to something else. I thought the question was about passing dynamic arguments. – briosheje Jun 28 '19 at 14:02

3 Answers3

4

Yes - spreading (ES6):

window[obj.method](...obj.params);

Make sure you're accessing the function correctly - if you declare it with var in the global scope, it'll be bound to the window. If not, it won't be accessible at all (bar eval, and that's bad practice).

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
3

For call function by string name:

window[obj.method](...obj.params)

Example:

let obj = {
    method: 'foo1',
    params: ['one', 'two']
}

function foo1(p1, p2) {
    console.log(p1, p2)
}

window[obj.method](...obj.params) // result: one two
HarisDev
  • 71
  • 4
2

You'll need the function to exist as a method of an object then you can invoke it dynamically with bracket notation [] and pass the name of the method as a string into the brackets as an index. You'll then use the spread operator ... to flatten the parameter array into a delimited list.

Others have shown this with the global window as the parent object, but (as we know) globals are generally bad, so just create your own.

Below, I am showing multiple methods and parameter choices and asking the user to type in which combination they want. Of course this input could be handled in many other ways.

// The methods must be stored in an object so that they can be accessed with
// bracket notation later.
let obj = {
  method1: function foo1(p1, p2) {
            console.log("method1 was called with: ", arguments);
  },
  method2: function foo1(p1, p2) {
            console.log("method2 was called with: ", arguments);
  },
  params1: ['one', 'two'],
  params2: ['three', 'four'],  
};

// Get the user's desired invocation requirements:
let choice = prompt("Enter 'method1' or 'method2'");
let args = prompt("Enter 'params1' or 'params2'");

// Pass the method name (as a string) into the object to extract the
// value of that property. Then invoke it with () and look up the correct
// parameter property in the same way. Flatten the parameter array with the
// spread operator (...).
obj[choice](...obj[args]);
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71