angular-google-analytics icon indicating copy to clipboard operation
angular-google-analytics copied to clipboard

Dynamically changing account ID after App init

Open 29er opened this issue 7 years ago • 4 comments

Hi, In my current setup, we don't know the Account (tracking id ) until we make a request to get environment info. So I need to wait to set the Account until after the app initializes, ( I do not have access to $http in a 'config' )

ie:

import analytics from 'angular-google-analytics'
let app = angular
    .module('app', [
        'angular-google-analytics',
    ])

app.config(function (AnalyticsProvider) {
   //**cant do this here**
    //AnalyticsProvider.setAccount('xxx')
    AnalyticsProvider
      .trackPages(true)
      .setPageEvent('$stateChangeSuccess')
      .setDomainName('none')
      .enterDebugMode(false)
      .startOffline(false)

})

So I need to be able to do something like this below. (but it won't work because 'setAccount' is not a function of Analytics) And if I try to manipulate the Analytics.configuration.accounts, it still gives me the #error "No account id set to create analytics script tag" and analytics does not work

This is essentially what Im trying to achieve

  app.run([ 'someService', 'Analytics', function(someService, Analytics) {
        someService.getAccount(resp => {
            **set up my Account tracker ID ,etc.**
    }])

Thanks for any advice!

29er avatar Oct 19 '16 15:10 29er

FYI i was able to do something like this to change the account info.

app.config(function (AnalyticsProvider) {
    AnalyticsProvider.setAccount('UA-XXX-dummyID')

    AnalyticsProvider
      .delayScriptTag(true)
      .ignoreFirstPageLoad(true)
      .trackPages(true)
      .trackUrlParams(true)
      .setPageEvent('$stateChangeSuccess')
      .logAllCalls(false)
      .setDomainName('none')
})

and in my 'run'

app.run([ 'someService', 'Analytics', function(someService, Analytics) {
        someService.getAccount(resp => {
            Analytics.configuration.accounts[0].tracker = resp.acct
             Analytics.createAnalyticsScriptTag()
    }])

proabably not the best way to do it but it works :)

29er avatar Oct 19 '16 19:10 29er

@29er Yeah, you figured out the way to do it that circumvents the config stage. This is purposefully mentioned in the README as unsupported because it should change in the future to prevent such monkeying with the configuration object post config phase.

The suggested way to do this is to pre-load the configuration from the server prior to starting angular.

I do see the merit though in exposing some configuration methods during the run phase if the 'delayScriptTag' was set to true. These extra configuration methods would then produce exceptions if called after the 'createAnalyticsScriptTag' was called.

justinsa avatar Oct 23 '16 03:10 justinsa

Working pattern:

AnalyticsProvider
  .setAccount('UA-XXX-defaultID')
  .delayScriptTag(true);
  .ignoreFirstPageLoad(true);

app.run([ 'someService', 'Analytics', function(someService, Analytics) {
  someService.getAccount(resp => {
    if(expression){
       // change default tracker if you need it
      Analytics.configuration.accounts[0].tracker = resp.acct
    }
    Analytics.registerScriptTags();
    Analytics.registerTrackers();
    if(resp.userID){
      // you can set any advanced configuration here
      Analytics.set('&uid', resp.userID);
    }
    Analytics.pageView(); // send data to Google Analytics
}]);

ViieeS avatar Jan 16 '17 15:01 ViieeS

If you are doing manual bootstrapping of your application you have access to the injector and therefore $http before your application bootstraps.

angular.element(document).ready(() => {
    const $http = angular.injector(['ng']).get('$http');
    const settingsRequest = { ... };

    $http(settingsRequest)
        .then((response) => {
            settings = response.data;
            angular.module('app').constant('yourAppSettings', settings);                
            angular.bootstrap(document, ['app'], { strictDi: true });
        });
});

...

app.config(function (AnalyticsProvider, yourAppSettings) {
    // You can do this now :)
    AnalyticsProvider
      .setAccount(yourAppSettings.accountId)
      .trackPages(true)
      .setPageEvent('$stateChangeSuccess')
      .setDomainName('none')
      .enterDebugMode(false)
      .startOffline(false);
});

seangwright avatar Jun 20 '17 20:06 seangwright