1

I have a function that has one required parameter and a variable number of parameters. I'm passing an array of blobs to the functions. A simplified version of the function looks like this:

function test(directory, blob0, blob1) {
  for (var argumentIndex = 1; argumentIndex < arguments.length; argumentIndex++) {
    var bytes = arguments[argumentIndex].getBytes();
    //do some things
  }
}

I'm using the rhino runtime so I can't use the spread operator. The closest I've come to making it work is by using the apply function, but I'm not sure how to also pass the required parameter (directory) in the test function above.

var blobs = [];
blobs[0] = getBlob();
blobs[1] = getBlob();
blobs[2] = getBlob();  

test.apply(null,blobs)  //doesn't set required parameter (directory)
gries
  • 250
  • 2
  • 7
  • *I'm using the rhino runtime* why? – TheMaster Feb 16 '20 at 06:36
  • @TheMaster Just being overly cautious since Google recently did the migration and I don’t want to spend time tracking down potential bugs. Not saying these are related, but it’s interesting that there is a recent bug with setting and getting protection using GAS. See here: https://issuetracker.google.com/issues/148894990 – gries Feb 16 '20 at 14:15
  • But that affects rhino as well. Doesn't it? In a way, you're affected regardless of whether you migrate or not. – TheMaster Feb 16 '20 at 14:16

2 Answers2

4
  • You want to use an array of blobs as the expanded values of blob0, blob1, blob2 at test(directory, blob0, blob1, blob2).
  • You want to use directory at test(directory, blob0, blob1, blob2) by adding directory.

If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.

In this answer, bind is used.

Modified script:

// sample getBlob(). This returns a blob.
function getBlob() {return Utilities.newBlob("sample", MimeType.PLAIN_TEXT)}

function test(directory, blob0, blob1, blob2) {
  Logger.log("%s, %s, %s, %s", directory, blob0, blob1, blob2) // <--- directory, Blob, Blob, Blob

  for (var argumentIndex = 1; argumentIndex < arguments.length; argumentIndex++) {
    var bytes = arguments[argumentIndex].getBytes();
    //do some things
  }
}

// Please run this function.
function myFunction() {
  var directory = "directory";

  var blobs = [];
  blobs[0] = getBlob();
  blobs[1] = getBlob();
  blobs[2] = getBlob();

  test.bind(this, directory).apply(null, blobs);
}
  • In this modified script, directory is added using bind.
  • When myFunction() is run, you can see directory, Blob, Blob, Blob at Logger.log("%s, %s, %s, %s", directory, blob0, blob1, blob2) in the function test(directory, blob0, blob1, blob2).

References:

If I misunderstood your question and this was not the direction you want, I apologize.

Tanaike
  • 181,128
  • 11
  • 97
  • 165
1

Use the unshift() function, it adds an element to the begining of an array

var blobs = [];
blobs[0] = getBlob();
blobs[1] = getBlob();
blobs[2] = getBlob();

blobs.unshift(directory)

test.apply(null,blobs)
izambl
  • 629
  • 3
  • 9
  • izambl, thank you for providing another way to accomplish my goal. I decided to use bind() instead since it doesn’t force me to modify the array or create another array. Also, the MDN docs specifically calls out using bind() for partially applied functions. – gries Feb 16 '20 at 13:58
  • Nice, I also think `.bind` is a better way to solve it – izambl Feb 17 '20 at 19:34