0

I currently have a bit of code that is as follows:

      $.when(aiFileGen, foeFileGen, foe2FileGen, playerFileGen).then(function (
        aiFiles,
        foeFiles,
        foe2Files,
        playerFiles
      ) {
        var files = _.assign({}, aiFiles, foeFiles, foe2Files, playerFiles);
        self.files(files);
        done.resolve();
      });

A snapshot self.files() is as follows:

Object {/pa/ai/unit_maps/ai_unit_map.json.ai: Object, /pa/units/sea/hover_ship/hover_ship.json.ai: Object, /pa/units/sea/fabrication_barge/fabrication_barge.json.ai: Object, /pa/units/sea/drone_carrier/drone/drone.json.ai: Object, /pa/units/sea/drone_carrier/carrier/carrier.json.ai: Object…}

The problem with this method is that it assumes a set number of parameters, but the number of parameters can change. Therefore I have tried to convert to something more dynamic.

      var filesToProcess = [aiFileGen, playerFileGen];

      filesToProcess.push(foeFileGen, foe2FileGen);

      $.when.apply($, filesToProcess).always(function () {
        self.files(_.assign({}, arguments));
        done.resolve();
      });

However, the output of self.files() is as follows:

Object {0: Object, 1: Object, 2: Object, 3: Object}

Where have I gone wrong in my conversion of method 1 to method 2?

Quitch
  • 89
  • 7

1 Answers1

1

The problem is that you always call _.assign({}, arguments) with 2 arguments. Instead you want to pass each argument in arguments as separate argument to _.assign.

This can be done similar to how you've also changed the $.when call. However you'll have to convert the arguments to an array first so you can add the additional {} argument.

var assignArgs = Array.prototype.push.apply([{}], arguments);
self.files(_.assign.apply(_, assignArgs);

However I'd recommend taking a look at the spread and rest syntax (...). This makes passing and accepting a variable amount of parameters a lot easier.

$.when.apply($, filesToProcess).always(function () {
  var assignArgs = Array.prototype.push.apply([{}], arguments);
  self.files(_.assign.apply(_, assignArgs);
  done.resolve();
});

// can be changed to

$.when(...filesToProcess).always(function () {
  self.files(_.assign({}, ...arguments));
  done.resolve();
});
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
  • Unfortunately, I'm working with Chromium 28, so can't use spread and rest. However, your answer worked like a charm, thanks. One correction I made is to add some missing brackets `self.files(_.assign.apply(_, ({}, arguments)));`, else it comes back as undefined. – Quitch Jul 13 '20 at 16:11
  • @Quitch That is a mistake on my part. [`apply`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) only accepts 2 arguments, the `this` argument and and argument list. Your proposed solution doesn't have the effect you think it has (you are using the [comma operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator)). It is the same as calling `_.assign.apply(_, arguments)`. This means you are mutating the first argument passed. This might not be an issue depending on your scenario. – 3limin4t0r Jul 13 '20 at 16:32
  • It appeared to work fine in my testing, however, I will look at switching to the edited answer to be safe, thanks. – Quitch Jul 14 '20 at 17:30
  • I ended up using `self.files(_.assign.apply(_, arguments);` as that appears to work correctly. The new method was generating an error about argument type. – Quitch Jul 14 '20 at 18:49