Imagine you have one Code.gs file for all your Apps Script code. It has some sort of JavaScript "class" Apple, global and local variables of the class and function that is using them:
function Apple (type) {
this.type = type;
this.color = "red";
}
Apple.prototype.getInfo = function()
{
return this.color + ' ' + this.type + ' apple';
};
var globalAppleItem = new Apple('global');
function onOpen() {
var ss = SpreadsheetApp.getActive();
var items = [
{name: 'AppleItem test', functionName: 'menuItem1'},
];
ss.addMenu('Custom Menu', items);
}
function menuItem1() {
var localAppleItem = new Apple('local');
Logger.log('localAppleItem.getInfo()=' + localAppleItem.getInfo());
Logger.log('globalAppleItem.color=' + globalAppleItem.color);
Logger.log('globalAppleItem.getInfo()=' + globalAppleItem.getInfo());
}
This script executes fine:
Script execution errors: No Logger output: [14-03-10 17:18:29:309 GST] localAppleItem.getInfo()=red local apple [14-03-10 17:18:29:309 GST] globalAppleItem.color=red [14-03-10 17:18:29:309 GST] globalAppleItem.getInfo()=red global apple
After some time you decide that moving the Apple class definition to a separate file is a good idea:
Apple.gs:
function Apple (type) {
this.type = type;
this.color = "red";
}
Apple.prototype.getInfo = function()
{
return this.color + ' ' + this.type + ' apple';
};
Code.gs:
var globalAppleItem = new Apple('global');
function onOpen() {
var ss = SpreadsheetApp.getActive();
var items = [
{name: 'AppleItem test', functionName: 'menuItem1'},
];
ss.addMenu('Custom Menu', items);
}
function menuItem1() {
var localAppleItem = new Apple('local');
Logger.log('localAppleItem.getInfo()=' + localAppleItem.getInfo());
Logger.log('globalAppleItem.color=' + globalAppleItem.color);
Logger.log('globalAppleItem.getInfo()=' + globalAppleItem.getInfo());
}
But behavior becomes strange:
Script execution errors: TypeError: Cannot find function getInfo in object [object Object]
Logger output: [14-03-10 17:16:08:830 GST] localAppleItem.getInfo()=red local apple [14-03-10 17:16:08:830 GST] globalAppleItem.color=red
By some means Apps Script "doesn't see" getInfo method definition. And at the same time, property color exists and initialized. I spent much time experimenting and searching the Web. Finally I found a solution which I'll provide as an answer to this post. But precise explanation of this behavior is what I haven't got yet and it would be great if someone could provide one.