2

Dear fellow programmers

I'm dealing with a atrange issues I've been trying to debug for the last two hours. I'm writing a web front end that receives commands from a server that are executed using the window.apply function. A triggerEvents function is used to handle all the different command and passes the arguments sent from the server to the appropriate function (see below code).

function triggerEvents(commands){
for (var index = 0; index < commands.length; index++){
    var command = commands[index];
    console.debug("execute");
    console.debug(command);
    console.debug(command.arguments);
    window[command.function].apply(null, command.arguments)
}

}

In general that works pretty well, however, one particular function (next code listing) is passed an array of strings but for some reason, only the first element is available in the function.

function updateAvailableBlocks(args) {
availableBlocks = []
for(i=0; i < args.length; i++) {
    availableBlocks[i] = args[i];
}

}

Now, when I inspect the debugger I can confirm that I do receive an array of Strings from the server and that that particular array is passed to window.apply as expected.

Debugger view inside triggerEvents()

But when I step into the execution of the function, I am only able to see the first element.

Debugger view inside upateActiveBlocks()

I made sure that all caches are deleted and that Im not using outdated code, but I can't think of something that would cause this. I'd be very grateful for your sharp minds on this.

Thanks in advance!

Omnibyte
  • 124
  • 3
  • 9
  • `args` is going to be only the first argument passed to `updateAvailableBlocks`. – dfsq May 16 '18 at 13:13
  • for the detail of the reason why your case behaves this way, `apply` will take your array of arguments and fire the function with separated arguments from your array (first array element will be first argument, the second will be a second argument, etc) – Kaddath May 16 '18 at 13:14

1 Answers1

2

Use .call instead of .apply. Apply spreads the arguments of passed array as if they were passed one by one. So if your function doesn't expect variable numbers of arguments and you are not handling them properly then it simply won't work as you would expect.

function foo(arg) {
  console.log(arg);
}

const arr = ['a', 'b', 'c'];
foo.apply(null, arr);
foo.call(null, arr);

Or you could use the rest operator with apply to achieve the same effect.

function foo(...arg) {
  console.log(arg);
}

const arr = ['a', 'b', 'c'];
foo.apply(null, arr);
Matus Dubrava
  • 10,269
  • 2
  • 24
  • 38