9

I'd like to write Javascript scripts for Google Apps Script using CoffeeScript, and I'm having trouble generating functions in the expected form.

Google Apps Script expects a script to contain top-level, named functions. (I may be using the wrong terminology, so I'll illustrate what I mean with examples...)

For example, this function is happily recognised by Google Apps Script:

function triggerableFunction() {
   // ...
}

... while this function is not (it will parse, but won't you won't be able to trigger it):

var nonTriggerableFunction;

nonTriggerableFunction = function() {
  // ...
};

I've found that with CoffeeScript, the closest I'm able to get is the nonTriggerableFunction form above. What's the best approach to generating a named function like triggerableFunction above?

I'm already using the 'bare' option (the -b switch), to compile without the top-level function safety wrapper.

The one project I've found on the web which combines CoffeeScript and Google App Script is Gmail GTD Bot, which appears to do this using a combination of back-ticks, and by asking the user to manually remove some lines from the resulting code. (See the end of the script, and the 'Installation' section of the README). I'm hoping for a simpler and cleaner solution.

4 Answers 4

15

CoffeeScript does not allow you to create anything in the global namespace implicitly; but, you can do this by directly specifying the global namespace.

window.someFunc = (someParam) -> 
    alert(someParam)
Sign up to request clarification or add additional context in comments.

1 Comment

This creates a anonymous function, not a named one. The anonymous function is then assigned to someFunc. Its obvious if you put a breakpoint in your new function and look at the stack trace.
3

Turns out this can be done using a single line of embedded Javascript for each function.

E.g. this CoffeeScript:

myNonTriggerableFunction = ->
  Logger.log("Hello World!")

`function myTriggerableFunction() { myNonTriggerableFunction(); }`

... will produce this JavaScript, when invoking the coffee compiler with the 'bare' option (the -b switch):

var myNonTriggerableFunction;

myNonTriggerableFunction = function() {
  return Logger.log("Hello World!");
};

function myTriggerableFunction() { myNonTriggerableFunction(); };

With the example above, Google Apps Script is able to trigger myTriggerableFunction directly.

Comments

1

This should give you a global named function (yes, it's a little hacky, but far less that using backticks):

# wrap in a self invoking function to capture global context
do ->
  # use a class to create named function
  class @triggerableFunction
    # the constructor is invoked at instantiation, this should be the function body
    constructor: (arg1, arg2) ->
      # whatever

4 Comments

That doesn't seem to generate a global named function. This is what it produces, when using the -b switch: (function() { return this.triggerableFunction = (function() { function triggerableFunction(arg1, arg2) {} return triggerableFunction; })(); })();
Did you run the code in a browser ? The function is global because it is attached to the global context. And it is named : triggerableFunction.name === "triggerableFunction". Of course, it does not generate a function statement, but I believe that is not what was asked.
The code ran within the Google Apps Script engine rather than a browser. I was indeed asking how to generate a function statement, which the Google Apps Script engine seems to require. The workaround used by 'gmail-gtd-bot' (using back-ticks) worked for me.
I need to attach a function to global namespace so I can call it after a pjax partial page load. This worked for me.
1

juste use @ in script, exemple of my code :

@isArray = (o)->
  Array.isArray(o)

it will be compiled in :

(function() {

  this.isArray = function(o) {
    return Array.isArray(o);
  };

}).call(this);

this = window in this case, so it's global function

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.