2

The codes for Google Analytics use a global _gaq object for the analytics commands. They advise to check if such an object already exists, like this:

var _gaq = _gaq || [];
// Command
_gaq.push(['_trackPageview']);

In CoffeeScript, this would look like this:

_gaq = _gaq or []

Which compiles to this:

(function() {
    var _gaq;
    _gaq = _gaq || [];
}).call(this);

How can I write a CoffeeScript code that will lead to the behaviour of the above Javascript?

Lanbo
  • 15,118
  • 16
  • 70
  • 147

3 Answers3

3

To make the _gaq variable available in the global scope you could write this in coffeescript:

_gaq = window._gaq ?= []

The javascript output:

var _gaq, _ref;
_gaq = (_ref = window._gaq) != null ? _ref : window._gaq = [];

This way you can latter call _gaq.push(['_trackPageview']);

There is another question in stackoverflow that talks about global variables in coffeescript that you might want to check.

Community
  • 1
  • 1
a--m
  • 4,716
  • 1
  • 39
  • 59
  • Like the other, it would still add `var _gaq` to the list of variables at the top of the scope, throwing out the `_gaq` that is already there. – Lanbo May 02 '13 at 12:17
  • Check my edit please, as I thing I could be leading you in a error with the first code example. – a--m May 02 '13 at 12:44
  • And one more edit, sorry to messup on the answer so much, much but I was not happy with it. This way you can still have _gaq as a private variable if you need so, and at the same time it will get the value of a possible defined _gaq object declared on the global scope. – a--m May 02 '13 at 13:23
1

You can conditionally assign a value to a variable iff it doesn't exist elegantly like this:

window._gaq ?= []

There are two tricky things going on here:

  1. Note that I'm referencing window._gaq. The Google Analytics JavaScript attaches the _gaq object directly on the window object. For more info, see: http://coffeescript.org/#lexical-scope

  2. Observe the ?= operator. This is CoffeeScript's existential operator, which provides for safer conditional assignment than ||=. For more info, Google for "CoffeeScript existential operator". (I'd link you directly, but I can't post another link, because I don't have enough reputation points yet.)

Finally, I've put together a gist that I use for Google Analytics tracking in CoffeeScript here: https://gist.github.com/brainix/4394158

0

You could do:

_gaq?.push ['_code']

Which will compile to:

// Generated by CoffeeScript 1.6.2
(function() {
  if (typeof _gaq !== "undefined" && _gaq !== null) {
    _gaq.push(['_code']);
  }

}).call(this);
TheHippo
  • 61,720
  • 15
  • 75
  • 100
  • But it would still add `var _gaq` to the top of the scope. – Lanbo May 02 '13 at 12:17
  • @LambdaDusk No it doesn't! At least when I compile the code from above to a JavaScript file. – TheHippo May 02 '13 at 12:19
  • But I still need to initialize the `_gaq` with `var _gaq = _gaq || []`. If I used yours, all the commands would be swallowed if the `_gaq` wasn't already there. – Lanbo May 02 '13 at 12:23
  • Okay, then I misunderstund you question or you weren't totally clear. As long as you just want to push the code to the `_gag` object if it exists then the code above should be fine. What should happen if `_gag` does not exist? – TheHippo May 02 '13 at 12:24
  • It should be initialized with `[]`. – Lanbo May 02 '13 at 12:35