2

I've configured a constant on a module like below(simplified version of my actual scenario):

var app = angular.module('app', []);
angular.config('AnalyticsConstant', function(){
  property: {
    click: 'clicked',
    swipe: 'swiped',
    externalLink: 'opened external link'        
  },
  page: {
    message: {
    list: 'Message listing',
    show: 'Message show'
    }
  }
}

Now I based on user action taken (say swipe), I want to trigger an analytics event. Since swipe/click or recognizing if an element has an external link, is something done on view level, I want to pass a hash to my controller method.

for example:

 <ion-list>
  <ion-item ng-repeat="message in messages track by $index" ui-sref="message_path({id: message.id})" class="item-text-wrap">
    <my-track-directive source='message', property='click'>
  </ion-item>  
 </ion-list>

Here certainly in myTrackDirective, I can read these two values and check if source/property key is available in AnalyticsConstant. Once found out, I'll also have to check if the value are key another key in AnalyticsConstant.source/property hash. Another pain will be, I'll need to stringify the keys source/property so that I can check in hash, however that's not a problem.

I was wondering if I can access the AnalyticsConstant in view, so that the directive line becomes something like:

    <my-track-directive source='AnalyticsConstant[page][message][list]', userAction='AnalyticsConstant[property][click]'>

I could think of three solutions:

  • Add inject it root scope. ie.

app.run(function($rootScope, AnalyticsConstant){ $rootScope.analyticsConstant = AnalyticsConstant }

But this is not a good solution, as if by mistake anyone changes $rootScope.analyticsConstant to something else, whole functionality may get screwed.

  • Inject in each controller and set it at $scope level.

$scope.analyticsConstant = AnalyticsConstant

This will be a lot of duplication. Also, it'll also not ensure if $scope.analyticsConstant won't get corrupted by mistake.(Though disaster will also be scoped and limited :) )

  • Write a function which returns AnalyticsConstant inside 'module.run' or may be inside each controller.

function getAnalyticsConstant = function(){ return AnalyticsConstant }

I particularly liked the third approach. But question remains where to place this (rootScope or controller-scope)?

My questions are:

  1. Is there any better way to access configured constant inside view in angular?
  2. What might be other problems with each of these approach I listed above?
  3. Is the directive approach is better or should I collect this data in some model and then pass it to analytics event function ?

Thanks

Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
Indyarocks
  • 643
  • 1
  • 6
  • 26

1 Answers1

2

I would use value to define constants:

app.value('AnalyticsConstant', function(){
  property: {
    click: 'clicked',
    swipe: 'swiped',
    externalLink: 'opened external link'        
  },
  page: {
    message: {
    list: 'Message listing',
    show: 'Message show'
    }
  }
}

So in each controller/directive you just nee to create instance, for example:

app.directive('myTrackDirective', ['AnalyticsConstant', function(AnalyticsConstant) {
        return {
            restrict: 'E',
            replace: true,
             scope: {/* ... */},
            templateUrl: 'some.html',

            link: function(scope) {
              scope.AnalyticsConstant = AnalyticsConstant;
            }
        };
    }]);

After you can call AnalyticsConstant from HTML


As a side note (doesn't refer to question):

Try to use MixPanel. Works great for Cordova-Ionic-Angular

Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
  • Isn't that what can be done using config as well? Though yes, putting AnalyticsConstant inside isolated scope can ensure it doesn't get changed inadvertently +1 for this :). – Indyarocks Sep 06 '14 at 12:48
  • 1
    @Indyarocks Actually you need *read only* behaviour. `app.config` has other goals then storage of constants – Maxim Shoustin Sep 06 '14 at 12:54
  • Btw, according to this discussion on [constant, value](http://stackoverflow.com/questions/13015523/angular-js-is-value-the-proper-way-to-set-app-wide-constant-and-how-to-retri) , shouldn't we use app.constant() in place of app.value() . Correct me if I'm missing anything here! Thanks for your last comment :) – Indyarocks Sep 06 '14 at 15:34
  • @Indyarocks you can use `constant`. There is no big difference. Only if you want constant to be injected into a module configuration function when `value` - no – Maxim Shoustin Sep 06 '14 at 15:51