Angularytics (Google Analytics for AngularJS directive) in production only

I am using Angularytics in my AngularJS web app. It works great, however I have three environments (development, testing and production) and they are collecting statistics from both. I would like to show the analytics for the production environment only.

I have analyzed many options, but they all have some problems. Now I would like to edit the angularytics.js script to add a condition, so in the code it will only do something if the $ rootScope.ENVIRONMENT constant is Production.

Something like:

(function () {
  angular.module('angularytics', []).provider('Angularytics', function () {
    if($rootScope.ENVIRONMENT == 'Production') {
    var eventHandlersNames = ['Google'];
    this.setEventHandlers = function (handlers) {
      if (angular.isString(handlers)) {
        handlers = [handlers];
      }
      eventHandlersNames = [];
      angular.forEach(handlers, function (handler) {
        eventHandlersNames.push(capitalizeHandler(handler));
      });
    };
    var capitalizeHandler = function (handler) {
      return handler.charAt(0).toUpperCase() + handler.substring(1);
    };
    var pageChangeEvent = '$locationChangeSuccess';
    this.setPageChangeEvent = function (newPageChangeEvent) {
      pageChangeEvent = newPageChangeEvent;
    };
    this.$get = [
      '$injector',
      '$rootScope',
      '$location',
      function ($injector, $rootScope, $location) {
        var eventHandlers = [];
        angular.forEach(eventHandlersNames, function (handler) {
          eventHandlers.push($injector.get('Angularytics' + handler + 'Handler'));
        });
        var forEachHandlerDo = function (action) {
          angular.forEach(eventHandlers, function (handler) {
            action(handler);
          });
        };
        var service = {};
        service.init = function () {
        };
        service.trackEvent = function (category, action, opt_label, opt_value, opt_noninteraction) {
          forEachHandlerDo(function (handler) {
            if (category && action) {
              handler.trackEvent(category, action, opt_label, opt_value, opt_noninteraction);
            }
          });
        };
        service.trackPageView = function (url) {
          forEachHandlerDo(function (handler) {
            if (url) {
              handler.trackPageView(url);
            }
          });
        };
        service.trackTiming = function (category, variable, value, opt_label) {
          forEachHandlerDo(function (handler) {
            if (category && variable && value) {
              handler.trackTiming(category, variable, value, opt_label);
            }
          });
        };
        $rootScope.$on(pageChangeEvent, function () {
          service.trackPageView($location.url());
        });
        return service;
      }
    ];
  }});
}());
(function () {
  angular.module('angularytics').factory('AngularyticsConsoleHandler', [
    '$log',
    function ($log) {
      var service = {};
      service.trackPageView = function (url) {
        $log.log('URL visited', url);
      };
      service.trackEvent = function (category, action, opt_label, opt_value, opt_noninteraction) {
        $log.log('Event tracked', category, action, opt_label, opt_value, opt_noninteraction);
      };
      service.trackTiming = function (category, variable, value, opt_label) {
        $log.log('Timing tracked', category, variable, value, opt_label);
      };
      return service;
    }
  ]);
}());
(function () {
  angular.module('angularytics').factory('AngularyticsGoogleHandler', function () {
    var service = {};
    service.trackPageView = function (url) {
      _gaq.push([
        '_set',
        'page',
        url
      ]);
      _gaq.push([
        '_trackPageview',
        url
      ]);
    };
    service.trackEvent = function (category, action, opt_label, opt_value, opt_noninteraction) {
      _gaq.push([
        '_trackEvent',
        category,
        action,
        opt_label,
        opt_value,
        opt_noninteraction
      ]);
    };
    service.trackTiming = function (category, variable, value, opt_label) {
      _gaq.push([
        '_trackTiming',
        category,
        variable,
        value,
        opt_label
      ]);
    };
    return service;
  }).factory('AngularyticsGoogleUniversalHandler', function () {
    var service = {};
    service.trackPageView = function (url) {
      ga('set', 'page', url);
      ga('send', 'pageview', url);
    };
    service.trackEvent = function (category, action, opt_label, opt_value, opt_noninteraction) {
      ga('send', 'event', category, action, opt_label, opt_value, { 'nonInteraction': opt_noninteraction });
    };
    service.trackTiming = function (category, variable, value, opt_label) {
      ga('send', 'timing', category, variable, value, opt_label);
    };
    return service;
  });
}());
(function () {
  angular.module('angularytics').filter('trackEvent', [
    'Angularytics',
    function (Angularytics) {
      return function (entry, category, action, opt_label, opt_value, opt_noninteraction) {
        Angularytics.trackEvent(category, action, opt_label, opt_value, opt_noninteraction);
        return entry;
      };
    }
  ]);
}());

      

I know a little Angular, however, I think I am not qualified enough to inject $ rootScope into this script. I always get $rootScope is not defined

.

UPDATE Regarding the comments below, I am updating the post: To add a script, this was my first approach. This can be done in a controller, for example:

if ($rootScope.ENVIRONMENT == 'Production') {    
            var head = document.getElementsByTagName('head')[0];
            var js = document.createElement("script");    
            js.type = "text/javascript";
            js.src =   "lib/plugins/angularytics-yanpy.js";
            head.appendChild(js);           
        }

      

This is angularytics-yanpy:

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-59702007-1', 'auto');

      

On the other hand, you need to add an angularytics script to your home page:

I think this will work in production environment. However, now in development a got a javascript error. Because angularytics.js needs the ga object created in the angularytics-yanpy.js. As this script is not created because is in development environment a get the javascript error.

      

I also added <script src="lib/plugins/angularytics.js"></script>

dynamically. But I got a new error because this script defines an angularity provider which is defined in the app.js file.

So the errors are related to each other, and so I tried to update the angularytics.js script to support the provider, but in case the environment is different from this production, it shouldn't do anything.

I'm probably not so clear, but it's not easy to explain. Just let me know if you need further clarification.

+3


source to share


4 answers


You don't have to set the environment to $rootScope

, it would be better to set it as a constant using grunt-ng-constant ( see the tutorial ).

To answer your question. You can inject rootScope into the provider using:

.provider('Angularytics', function ($rootScope) {});

However, this is not a good solution to your common problem.

A good method would be to determine the hostname and set separate Google Analytics Properties for:



  • Development of
  • staging
  • production

In the html google analytics script add this switch statement.

var gaProp;

switch (window.location.hostname) {
    case 'www.domain.com':
        gaProp = 'UA-123456'; // production
        break;
    case 'staging.domain.com':
        gaProp = 'UA-654321'; // staging
        break;
    default:
        gaProp = 'UA-000000'; // development
}

// Google Analtics
(function (i, s, o, g, r, a, m) {
    i['GoogleAnalyticsObject'] = r;
    i[r] = i[r] || function () {
                (i[r].q = i[r].q || []).push(arguments)
            }, i[r].l = 1 * new Date();
    a = s.createElement(o), m = s.getElementsByTagName(o)[0];
    a.async = 1;
    a.src = g;
    m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', gaProp, 'auto');

      

Note. I am setting gaProp on ga event (last line).

This way, you can set up different targets and filters for each property, and all your test data does not interfere with each other.

+13


source


You probably want to set up a filter in your Google Analytics data views.

  • Click Add Filter

    .
  • Give the filter a name.
  • Set the filter to type Custom

    .
  • Select the include

    Set the filter field to a value button Hostname

    .
  • Then install the template like this: www\.yourdomain\.com$

    (Of course, if you don't use ".com" you are using the TLD you are using).
  • Select the profiles for which you would like to enable this filter.


This is probably the easiest way to do what you want. You are filtering out any data that does not belong to the domain.

0


source


Since you are using Grunt to build your application here, a method I have successfully implemented in one of my applications at work.

I created 2 tracking codes in Google Analytics, one for testing environment , one for production . I see that you are not planning to track the environment and that was my original plan. However, it is good to check that everything works with Google Analytics as well, and it will be very helpful if you start tracking user events (like how many users click on a certain button, etc.). Fortunately, tracking codes are free ...

I used the Grunt preprocess to conditionally write the appropriate code.

In mine, index.html

I put my GA code at the bottom:

  <script>
     (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  <!-- @if DEV -->
  ga('create', 'UA-554030000-1', 'auto');
  <!-- @endif -->
  <!-- @if PRODUCTION -->
  ga('create', 'UA-554030000-2', 'auto');
  <!-- @endif -->
  </script>  

      

Then just set up your task:

preprocess : {
  html: 'build/index.html',
  options: {
    inline : true
  }
  production : {
  options: {
   context : {
    PRODUCTION: true
   }
  }
 },
 dev : {
  options: {
    context : {
     DEV: true
   }
 }

      

Then running grunt preprocess:production

or grunt preprocess:dev

will result in the removal of unused code and the creation of the corresponding file. This task can then be included in your build process (I use the type flag grunt build --dev

to direct the script to the correct path).

0


source


It should be as simple as turning on design mode to stop sending tracking information. Straight from the docs, it says to do the following in your app config.

In two environments, you don't want the tracking to be dispatched, set to true and when pushing to production, just return it to false using the build script.

$analyticsProvider.developerMode(true);

      

0


source







All Articles