0

My company requires I send my tracking data to a global function defined in the <head> so the analytics team can work on it. They don't know angular 2, frameworks, etc. and want it exactly like in docs: no exceptions.

<head>
...
  <script type="text/javascript">

    function sendAnalytics(data) {
      console.log("GTM data sent" + data);

    };
    var gaData = [_dl];
</script>
</head>

So in my angular services I call the globally defined function like so

window['sendAnalytics'](GTMData_Object);

This works on page load but as I go to various routes, the globally defined function no longer runs anymore?

I tried NG zone like this but still no luck.

 this.zone.runOutsideAngular(() =>  window['sendAnalytics'](GTMData_Object);)

I know there are better ways to handle Google tag manager in Angular 2 but obviously, I'm not allowed to do that(I tried!).

EDIT: The site using routing for every using interaction we want to track. I always see the console.log() of the data coming in so it's passing through to service good. I stop getting logs in global function after the initial page load.

Example of service method

 search_result_clicks(
        search_term: string,
    ): void {
        let trackObject = {
            'site_events': {
                'search_click': search_term
            };       
         console.log(trackObject);
        //push to GTM via global function defined in header
            try { window['sendAnalytics'](trackObject); } 
catch (err) {
 this.handleError(err); 
}
        }

EDIT: if I put the scripts tag and functions inside the <app-root> element then angular can get access to it regularly as a global. Doesn't work for Head or Body. It's still on index.html and that seems as close as we can get.

EDIT2: works in body too IF put below <app-root>

So for anybody else in this situation....

global functions in header + angular 2 = bad ; must put below or in app-root

global variables of strings, arrays, objects in header + angular 2 = okay; GTM worked fine far as I could tell so far.

global functions and variables defined in index html below app-root or bottom of page = okay.

deek
  • 1,055
  • 1
  • 9
  • 26

2 Answers2

1

Based on your question, I understand that you want to track every navigated page. For that, you may use router event to track navigation. But I think this feature is introduced in Angular4.

OR

I tried a similar code and it works for me. Are you calling this method in a constructor? Because it created only one time.

window['sendAnalytics'](GTMData_Object) // I call it like that and it works

https://plnkr.co/edit/m7NHXIC6JrXLaW9wdwu1?p=preview

0

You can provide your external function to angular as provider and share that all over the application. when ever you will call that, it will call the global function.

you can look into this answer which is similar to your problem.

window.sharedService = new SharedService();

@NgModule({
  providers: [{provide: SharedService, useValue: window.sharedService}],
  ...
})
class AppModule1 {}

@NgModule({
  providers: [{provide: SharedService, useValue: window.sharedService}],
  ...
})
class AppModule2 {}


class MyComponent {
  constructor(private zone:NgZone, private sharedService:SharedService) {
    sharedService.someObservable.subscribe(data => this.zone.run(() => {
      // event handler code here
    }));
  }
}

Hope it helps

Aniruddha Das
  • 14,517
  • 13
  • 83
  • 111