4

Preface

I am posting this to warn others of a potential bug in google.script.run, to present a possible work-around, and to solicit further community insights into what might be going on.

The Problem

I am passing a large data object to a server-side function invoked via google.script.run. Here is it what it looks like on the client-side before the call to Google.script.run (obtained by JSON.stringify'ing and outputting through an alert box):

{"roundStartTime":"12:00:00","roundFinishTime":"12:45:23","holeData":{"1":{"strokes":1,"finishTime":"12:02:00"},"2":{"strokes":6,"finishTime":"12:04:00"},"3":{"strokes":7,"finishTime":"12:06:00"},"4":{"strokes":8,"finishTime":"12:08:00"},"5":{"strokes":9,"finishTime":"12:10:00"},"6":{"strokes":10,"finishTime":"12:12:00"},"7":{"strokes":11,"finishTime":"12:14:00"},"8":{"strokes":12,"finishTime":"12:16:00"},"9":{"strokes":13,"finishTime":"12:18:00"},"10":{"strokes":1,"finishTime":"12:30:00"},"11":{"strokes":11,"finishTime":"12:33:00"},"12":{"strokes":8,"finishTime":"12:35:00"},"13":{"strokes":3,"finishTime":"12:37:00"},"14":{"strokes":7,"finishTime":"12:39:00"},"15":{"strokes":10,"finishTime":"12:40:00"},"16":{"strokes":11,"finishTime":"12:42:00"},"17":{"strokes":13,"finishTime":"12:45:00"},"18":{"strokes":6}}}`

And here's the same object as it is received on the server-side (obtained by JSON.stringify'ing and outputting through Google's Logger.log function):

{"roundStartTime":"12:00:00","holeData":{"11":{"strokes":11,"finishTime":"12:33:00"},"12":{"strokes":8,"finishTime":"12:35:00"},"13":{"strokes":3,"finishTime":"12:37:00"},"14":{"strokes":7,"finishTime":"12:39:00"},"15":{"strokes":10,"finishTime":"12:40:00"},"16":{"strokes":11,"finishTime":"12:42:00"},"17":{"strokes":13,"finishTime":"12:45:00"},"18":{"strokes":6,"finishTime":null},"1":{"strokes":1,"finishTime":"12:02:00"},"2":{"strokes":6,"finishTime":"12:04:00"},"3":{"strokes":7,"finishTime":"12:06:00"},"4":{"strokes":8,"finishTime":"12:08:00"},"5":{"strokes":9,"finishTime":"12:10:00"},"6":{"strokes":10,"finishTime":"12:12:00"},"7":{"strokes":11,"finishTime":"12:14:00"},"8":{"strokes":12,"finishTime":"12:16:00"},"9":{"strokes":13,"finishTime":"12:18:00"},"10":{"strokes":1,"finishTime":"12:30:00"}}."roundFinishTime":"12:45:23"}

As you can see, the object appears to be identical, except that the properties of "holeData" appear in a different order on the server-side. The problem is NOT that object properties are ordered differently, however; it is that I simply can't access properties on the server side. Please read on for more details.

On the server side, I can confirm that the holeData property has the following (sub)properties by JSON.stringify'ing a call to Object.keys(data.holeData):

["11","12","13","14","15","16","17","18","1","2","3","4","5","6","7","8","9","10"]

However, When I then attempt to access the "strokes" (sub)property of any one of these objects, e.g.:

data.holeData["1"].strokes --or-- data.holeData["1"]["strokes"], I get an error:

Execution failed: TypeError: Cannot read property "strokes" from undefined.

So something unexpected happened to the object when it was transferred from the client to the server side.

Note: I have carefully read the rules for legal parameters to google.script.run functions, and my object does not appear to violate any of them. It's composed solely of string and integer data.

The Solution

I have fixed the issue by applying JSON.stringify() to the object on the client side, and then JSON.parse() on the server-side. When I serialize/deserialize in this way, I am able to access all object properties on the server-side.

Any idea what is happening with this object? Is this a bug or a feature?

Rubén
  • 34,714
  • 9
  • 70
  • 166
SpeedGolfer
  • 255
  • 3
  • 13
  • I don't think that's a bug. It's just that javascript doesn't care about the order of the key of an object. `Object.keys` is not guaranteed to return the same order on one side, never mind an object that being transfered from one side to the other and being reconstructed from scratch – ibrahim mahrir Apr 18 '18 at 23:20
  • https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – ibrahim mahrir Apr 18 '18 at 23:24
  • 1
    Hi ibrahim, The ordering doesn't matter. What matters is whether I can access object properties. The fact remains that on the client side I can, but on the server side I can't, even though the object has the same properties on both sides. Can you explain this? – SpeedGolfer Apr 18 '18 at 23:54
  • What kind of project are you using? Is this occurring on a dialog, sidebar or web app? I'm using a standalone project for an add-on that includes an installable trigger and a sidebar. The sidebar works fine when running with "test as add-on" but not when running it as a library in a bound to spreadsheet project. Your solution doesn't work for me (yet?). – Rubén May 28 '18 at 21:34

0 Answers0