Dynamically changing account ID after App init
29er opened this issue · 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!
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 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.
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
}]);
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);
});