Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extend Google apps script classes

I am trying to extend class Sheet in a script and i get Sheet is undefined when it tries to execute the folowing:

Sheet.prototype.moveColumn = function(SourceIndex, DestinationIndex){
  var source = this.getRange(1, SourceIndex, ss.getLastRow(), 1).getValues()
  var move = SourceIndex-DestinationIndex>0 ? sheet.getRange(1, DestinationIndex,  ss.getLastRow(), SourceIndex-DestinationIndex).getValues() : sheet.getRange(1, SourceIndex, ss.getLastRow(), DestinationIndex-SourceIndex).getValues();
  sheet.getRange(1, DestinationIndex, source.length, 1).setValues(source);
  SourceIndex-DestinationIndex>0 ? sheet.getRange(1, DestinationIndex+1, move.length, move[0].length).setValues(move) : sheet.getRange(1, SourceIndex, move.length, move[0].length);
  return this
}
like image 443
alexanderjh Avatar asked Jul 02 '13 18:07

alexanderjh


2 Answers

So far, only Google, not its users, can do this, specifically, in GAS(Google Apps Script), can extend {the classes which are not native JavaScript, which are the classes by Google}, so can do something as ‘Sheet.prototype.MyMethod= function(..) {..}’, where these classes by Google are defined under ‘Classes’ under each {functionality component, as first one ‘Calendar’} in the official GAS reference.

  1. Being able to extend Google's classes would be quite handy and natural, including the known workarounds (detailed below) are also fairly ugly. Indeed I this answer's originator post this answer because foremost I regularly want to make such extensions this myself so empathize with & want to help others trying do the same. But...
  2. Why Google prevents this, at least for a user's own use, appears unknown to users. Though...
  3. Google being upsetting here, by both crippling something they offer & not telling why, is sadly not surprising as both:
    1. While Google's GAS features being mostly JavaScript and indeed that its arguably best asset, GAS actually has many more upsetting & undocumented limitations compared to JS.
    2. Google upsettingly almost never tells users why they end their products nor even warns before such removal decision is made, so it would not seem surprising to see Google also upsettingly not telling users why they cripple their products.
  4. The, else an, official report of this problem is the issue tracker's Issue 708 (from this Qs 1st answer), which is the/an official web discussion on the problem, including where apparently-anyone can vote for this ability by, when signed into Google, clicking on the discussion's star or/and commenting there requesting it.
  5. Known attempts, both direct & indirect, all fail:
    1. NP4CP4: ‘Sheet.prototype .MyMethod= ..' gets ‘ReferenceError: "Sheet" is not defined.’
    2. NP3LNQ: ‘SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().constructor.prototype .MyMethod= ..’ gets ‘TypeError: Cannot read property "prototype" from undefined.’
    3. NP4CQR: ‘SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().__proto__ .MyMethod= ..’ gets ‘TypeError: Cannot set property "MyMethod" of undefined to "(class)@26d5fab1".’
    4. NP4K1W: ‘Object.getPrototypeOf(SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()) .MyMethod= ..’ gets ‘TypeError: Cannot set property "MyMethod" of null to "(class)@b73c746".’
  6. A few more details of the problem are at {earlier more-specific request} answer ‘How can I extend UiApp with a new function?'
  7. Workarounds include:
    1. NP4J3T: Code every method to be added instead as an ordinary function call (so then sacrificing method functionality).
    2. NP4IGZ: A partial-workaround, true for this & many situations where a class isn't to extended, is define & instead-use a new class which stores a link to the object (in the original class) to be extended, and in the new class add the new methods needed, and (the painful part) in the new class also re-implement every of the original class's existing methods (which could change!) which will be needed where each is implemented as just (delegating to) a call to the original method.
      1. To suggest this workaround might be why Issue response c3 was posted, which seems like it could be trying to refer to GAS wrapper class example HeaderRow.
like image 69
Destiny Architect Avatar answered Sep 30 '22 19:09

Destiny Architect


You cannot extend prototypes of Google's Classes. You can find comments about this on the issue tracker, Issue 708

like image 37
Mogsdad Avatar answered Sep 30 '22 17:09

Mogsdad