When helper functions really help [your analytics]

Posted By Brad Czerniak on Monday, October 6, 2014 - 11:45

In a previous blog post, I went over how to track on-page events using Google Analytics. That post included a helper function called ga_event() that wrapped Google Analytics' method:

  1. _gaq.push(['_trackEvent', Category, Action, Label, Value]);

If you use GA, you're likely aware that they've switched tracking codes to Universal Analytics. The above code no longer works in Universal Analytics.

Thank goodness for ga_event()

If, instead of creating a helper function, we had used _gaq.push() throughout our JavaScript code, we would have had to update every event throughout the code. Thankfully the ga_event() helper function can be updated to work with both the original analytics and universal.

The original function:

  1. /**
  2.  * Wrapper function for Google Analytics events
  3.  */
  4. function ga_event(params) {
  5.   params.splice(0, 0, "_trackEvent");
  6.   if (typeof _gaq === "object") {
  7.     _gaq.push(params);
  8.   }
  9. }

The new function, with Universal analytics support:

  1. /**
  2.  * Wrapper function for Google Analytics events.
  3.  */
  4. function ga_event(params) {
  5.   if (typeof _gaq === "object") {
  6.     params.splice(0, 0, "_trackEvent");
  7.     _gaq.push(params);
  8.   }
  9.   else if (typeof ga === "function") {
  10.     params.splice(0, 0, 'send', 'event');
  11.     ga.apply(null, params);
  12.   }
  13. }

What the new bit of code does

In Drupal (or in regular PHP), the call_user_func_array() function lets you pass an array as the arguments for the function being called through it. This is useful for the Drupal hook system, for things like access function overrides, and for general abstracting.

JavaScript has something similar: the Function.prototype.apply() method. The second argument is an array of arguments to pass. Since ga_event took an array of parameters in the first place, it was as simple as prepending the new arguments (send, event) instead of (_trackEvent) and applying the function instead of calling the _gaq object's push() method.

The conditional still means that the function does nothing if neither type of analytics is available. The second condition just does a basic check to ensure the Google Analytics function is available to call.

A rule of thumb

APIs change. Rather than relying on objects existing from external scripts, it is often advisable to abstract away such calls.