1
function convertToEnts(formObject){
  var sheet = SpreadsheetApp.getActiveSheet();
  var columns = sheet.getRange(1,1,1, sheet.getLastColumn()).getValues()[0];
  var columnValues = String(columns).split(",");  //this is something I tried on the advise of https://stackoverflow.com/questions/17044825/indexof-returning-1-despite-object-being-in-the-array-javascript-in-google-sp
  var data = sheet.getRange(2, 1,sheet.getLastRow()-1,sheet.getLastColumn()).getValues();
  for (var i=0;data.length;i++){
    row = data[i];
    var entity = {}
    //formObject: {identity=lat,...,other form attributes here}
    for (var key in formObject){
      Logger.log(formObject[key]);
      Logger.log(typeof formObject[key]);
      Logger.log(columnValues);    
      var indexOfKey = columnValues.indexOf(formObject[key]);
      Logger.log(indexOfKey);
      var value = formObject[key];    //row[indexOfTimestamp]
      entity[key] = row[indexOfKey];
    }
  }
}

Logs:

[17-06-15 15:48:02:071 PDT] lat 
[17-06-15 15:48:02:072 PDT] string
[17-06-15 15:48:02:072 PDT] [a, b, c, lat]
[17-06-15 15:48:02:073 PDT] -1.0

So the formObject[key] or value is lat. The type is a string (all good so far). The column looks like [a,b,c,lat]. And I basically want to return the index of lat which should be 3 I think. Im struggling with that indexOfKey variable. Anything I try returns a -1 as if the string is not in the array. Any suggestions?

1
  • What are the type and values fo formObject? The code has a several lines that is very likely that aren't required to reproduce the problem. See minimal reproducible example. Commented Jun 16, 2017 at 1:09

1 Answer 1

1

This is actually a known bug (there's a ticket for it in google's issue tracker).

Simplest workaround is to add the following polyfill to your code (sourced from MDN).

// Production steps of ECMA-262, Edition 5, 15.4.4.14
// Reference: http://es5.github.io/#x15.4.4.14
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {

    var k;

    // 1. Let o be the result of calling ToObject passing
    //    the this value as the argument.
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }

    var o = Object(this);

    // 2. Let lenValue be the result of calling the Get
    //    internal method of o with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = o.length >>> 0;

    // 4. If len is 0, return -1.
    if (len === 0) {
      return -1;
    }

    // 5. If argument fromIndex was passed let n be
    //    ToInteger(fromIndex); else let n be 0.
    var n = fromIndex | 0;

    // 6. If n >= len, return -1.
    if (n >= len) {
      return -1;
    }

    // 7. If n >= 0, then Let k be n.
    // 8. Else, n<0, Let k be len - abs(n).
    //    If k is less than 0, then let k be 0.
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

    // 9. Repeat, while k < len
    while (k < len) {
      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the
      //    HasProperty internal method of o with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      //    i.  Let elementK be the result of calling the Get
      //        internal method of o with the argument ToString(k).
      //   ii.  Let same be the result of applying the
      //        Strict Equality Comparison Algorithm to
      //        searchElement and elementK.
      //  iii.  If same is true, return k.
      if (k in o && o[k] === searchElement) {
        return k;
      }
      k++;
    }
    return -1;
  };
}
Sign up to request clarification or add additional context in comments.

8 Comments

Im not exactly sure where to add this. Here is my code with where I thought it should go: bpaste.net/show/eb1b77dfe2c5 . I think it actually is using the new function because its not -1 anymore but now its just undefined on line 112. Is this what you meant?
Not exactly. This code should not be pasted within your function, its needs to be available globally. You can paste it at the top of your current script file, or you can paste it into a new script file by going to the menu and selecting File>New>Script File.
hmm. Im not sure if that works. I put it in a new file called indexOf.gs. In it i log: Logger.log('using the external file'); This never shows up in the logs however.
Looking at the code in bpaste I think you might have an error on line 111. You invoked the indexOf on 'columns'. Looking at your original code snippet above it looks like you need to invoke it on 'columnValues'
Thanks for checking it out. I think those are basically the same? Just in case, I used columnValues and put the pollyfill at the top of the file in this one: bpaste.net/show/4986375bb9a6. Check lines 114-119 and the paste at the bottom
|

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.