1

I'm aware that global variables in google apps script have some issues (or, rather, different ways of working than "normal" code):

Issues with global variables in Google App Script

How to define global variable in Google Apps Script

Global variables in Google Script (spreadsheet)

and many more examples, but the question is, in the Google Apps script documentation, they mention that in the onOpen function, there is passed the event object, which contains a source property, which is linked to the current document:

source A Document object, representing the Google Docs file to which the script is bound.

Document

Now, what would be the point of giving us access to this source if you would have to call DocumentApp.getActiveDocument() anyway? I tried making a global variable at the top of the code stating:

var doc;

then in the onOpen(e) function, setting it to: doc = e.source, which works fine in that function, but when I want to use it in another function called by the client, the "global" variable "doc" is undefined or null, so how can I set it up so I don't have to call DocumentApp.getActiveDocument() every time the client clicks something? Because it takes about 50-70ms, which even though its pretty fast, but it could be faster... any workarounds for this?

basically: how do I store DocumentApp.getActiveDocument() in a reusable variable? And if I can't, why is the source property provided in the event object in onOpen? (the fact that it is implies that its possible to store it somewhere perhaps)

1 Answers1

3

I think e.source is provided just so you don't have to call DocumentApp.getActiveDocument() in your trigger, as you pointed out. This is useful because you may want to manipulate the document, so having it provided means that you don't need to make an additional call.

Having a global var doc = e.source won't work because the script is re-instantiated every time you run it. So once your onOpen() finishes running, none of your variable values will persist.

This won't work, because the value of doc will be undefined after onOpen() terminates.

var doc;

function onOpen(e) {
  doc = e.source;
}

function foo() {
  DocumentApp.getUi().alert(doc.getName());
}

This will work, because it's the same script instance as when onOpen() was called, meaning that the value of doc is defined.

var doc;

function onOpen(e) {
  doc = e.source;
  foo();
}

function foo() {
  DocumentApp.getUi().alert(doc.getName());
}

Ultimately, the best way to have doc work globally is to just save DocumentApp.getActiveDocument() to it. That means DocumentApp.getActiveDocument() will be called every time you execute the script, regardless of whether you need the document or not. So consider whether you really need it available globally.

var doc = DocumentApp.getActiveDocument();

function onOpen(e) {
  // do something
}

function foo() {
  DocumentApp.getUi().alert(doc.getName());
}
Diego
  • 9,261
  • 2
  • 19
  • 33