Skip to content

Instantly share code, notes, and snippets.

@josephwegner
Created November 11, 2014 20:20
Show Gist options
  • Save josephwegner/07edea667abedd34368f to your computer and use it in GitHub Desktop.
Save josephwegner/07edea667abedd34368f to your computer and use it in GitHub Desktop.
GTM, GA, Angular, ui-router bug

I am building a SPA using Angular.js. We use Google Tag Manager to load in most of our analytics/marketing scripts, which includes Google Analytics. I am also using ui-router to manage states/views.

I would like to send pageview events off to Google Analytics whenever a user browses to a different state in my app. Part of the complexity in doing this with GTM is that GTM creates a named tracker. That means that all GA events need be prepended with the tracker name. That would usually look like this:

 ga('trackerName.send', 'pageview', {page: '/a/path/', title: 'A Title'});

GTM uses a randomly generated tracker name, so the tracker name needs to be grabbed at runtime. That can be done fairly simply with GA's getAll function. If you want to send the pageview event to all trackers, you would simply do:

 var allTrackers = ga.getAll();
 for(var i=0; i<allTrackers.length; i++) {
   ga.send(allTrackers[i].getName()+".send", "pageview", {page: '/a/path', title: 'A Title'});
 }

This works great for most of my pageview events. However, there is a race condition between when ui-router fires the initial view's $stateChangeSuccess (which is where I trigger the GA pageview), and when analytics.js is loaded.

Prior to analytics.js being loaded, Google Analytic's snippet creates a faux ga object, that you can send events to. This faux object does not have the rest of the ga functions on it, so you can not run getAll. Without the getAll function, I cannot get the tracker name and I cannot send pageview events.

As far as I can tell, Google Analytics does not provide any callbacks or events for when analytics.js is finished loading, so there is no way to tell when I will be able to start sending events. Right now I am using an $interval to check for the existence of ga.getAll, but that is not a very performant or ideal solution.

Is there any other way to recognize when analytics.js has finished loading? Or any other way to send events to a named tracker, without having access to getAll?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment