Reputation: 1159
I am trying to de-construct a Google-Team's script for getting a report from AdWords and writing it into Google Sheets spreadsheet. I am testing it in Apps editor and getting the "Cannot read of undefined..." error.
I currently have two .gs files in my project:
1. Function definition ("class"), empty_row.gs
file:
function SpreadsheetAccess(spreadsheetUrl, sheetName) {
this.spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
this.sheet = spreadsheet.getSheetByName(sheetName);
this.findEmptyRow = function(minRow, column) {
var values = this.sheet.getRange(minRow, column, this.sheet.getMaxRows(), 1).getValues();
for (var i = 0; i < values.length; i++) {
if(!values[i][0]) {
return i + minRow;
}
}
return -1;
};
this.addRows = function(howMany){
this.sheet.insertRowsAfter(this.sheet.getMaxRows(), howMany);
};
this.writeRows = function(){
this.sheet.getRange(startRow, startColumn, rows.length, rows[0].length).setValue(rows);
};
}
2. and a main.gs
file where I instantiate the object:
var spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/someurl/edit#gid=1540200210';
var sheetName = 'baba';
function main() {
var object = SpreadsheetAccess(spreadsheetUrl, sheetName);
var emptyRow = object.findEmptyRow(1, 1);
Logger.log("The empty row is: %s", emptyRow);
}
When I run main{}
I am getting this:
TypeError: Cannot call method "findEmptyRow" of undefined. (line 6, file "main")
Why is my object undefined? I have defined:
What gives? thanks!
Upvotes: 0
Views: 8273
Reputation: 10030
You shouldn't be trying to modify objects you do not own with the use of this
. Especially in Google Apps Script. AFAIK this
actually refers to the object that contains all the services code for Apps Script itself.
Create your own objects and pass those around instead of changing the object with global scope, while it will technically work to stuff everything into that object and reference it, it's discouraged.
I was incorrect in my reasoning. The problem I posted still stands though.
The Problem:
object
is undefined because you are not returning a value from SpreadsheetAccess()
. Nothing has been defined as nothing has been returned.
Solution 1
Here is your code with two changes. Newing up the SpreadsheetAccess function, and changing spreadsheet.getSheetByName(sheetName);
to this.spreadsheet.getSheetByName(sheetName);
var spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/someurl/edit#gid=1540200210';
var sheetName = 'baba';
function main() {
var object = new SpreadsheetAccess(spreadsheetUrl, sheetName);
var emptyRow = object.findEmptyRow(1, 1);
Logger.log("The empty row is: %s", emptyRow);
}
function SpreadsheetAccess(spreadsheetUrl, sheetName) {
this.spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
this.sheet = this.spreadsheet.getSheetByName(sheetName);
this.findEmptyRow = function(minRow, column) {
var values = this.sheet.getRange(minRow, column, this.sheet.getMaxRows(), 1).getValues();
for (var i = 0; i < values.length; i++) {
if(!values[i][0]) {
return i + minRow;
}
}
return -1;
};
this.addRows = function(howMany){
this.sheet.insertRowsAfter(this.sheet.getMaxRows(), howMany);
};
this.writeRows = function(){
this.sheet.getRange(startRow, startColumn, rows.length, rows[0].length).setValue(rows);
};
}
Solution 2 Here is my modified code, this code works, I already tested it with my own spreadsheet:
var spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/someurl/edit#gid=1540200210';
var sheetName = 'baba';
function main() {
var myObject = SpreadsheetAccess(spreadsheetUrl, sheetName);
var emptyRow = myObject.findEmptyRow(1, 1);
Logger.log("The empty row is: %s", emptyRow);
}
function SpreadsheetAccess(spreadsheetUrl, sheetName) {
var myObject = {};
myObject.spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
myObject.sheet = myObject.spreadsheet.getSheetByName(sheetName);
myObject.findEmptyRow = function(minRow, column) {
var values = myObject.sheet.getRange(minRow, column, myObject.sheet.getMaxRows(), 1).getValues();
for (var i = 0; i < values.length; i++) {
if(!values[i][0]) {
return i + minRow;
}
}
return -1;
};
myObject.addRows = function(howMany){
myObject.sheet.insertRowsAfter(myObject.sheet.getMaxRows(), howMany);
};
myObject.writeRows = function(startRow, startColumn, rows){
myObject.sheet.getRange(startRow, startColumn, rows.length, rows[0].length).setValue(rows);
};
return myObject;
}
Upvotes: 1