3

I got a problems trying to implement google analytics in angular2. According to information I found and as example, in this post it seems pretty easy. But so far I didn't found any example how to do it not from .html but from .ts instead.

I am trying to make a private method with google analytics and then call it in constructor. Something like that.

constructor() {
  this.initializeAnalytics();
}

private initializeAnalytics() {
    (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');

    ...
    ...
}

But just placing google analytics code is not working (Error: supplied parameters do not match any signature of call target). I probably am doing it in wrong way.

How can I accomplish this?

Community
  • 1
  • 1
Olegs Jasjko
  • 2,128
  • 6
  • 27
  • 47

2 Answers2

7

This is how I did it.

You need to put the ga code into your index.html. (do not forget to comment the following line : //ga('send', 'pageview');)

Then you need to declare the ga function into your app.component.ts file, after the imports :

import { ... } ...;

declare var ga:Function;

@component(...)

Then you could subscribe to the route change event in your app.component.ts and send the ga data like this :

this.router.events.subscribe((event:Event) => {
    // Send GA tracking on NavigationEnd event. You may wish to add other 
    // logic here too or change which event to work with
    if (event instanceof NavigationEnd) {
        // When the route is '/', location.path actually returns ''.
        let newRoute = this.location.path() || '/';
        // If the route has changed, send the new route to analytics.
        if (this.currentRoute != newRoute) {
            ga('send', 'pageview', newRoute);
            //console.log('would send to ga: ' + newRoute);
            this.currentRoute = newRoute;
        }
    }
});
Ploppy
  • 14,810
  • 6
  • 41
  • 58
  • Thanks for answer, but this is exactly the same thing what i found (watch linked url) – Olegs Jasjko Nov 21 '16 at 11:53
  • I have got a code like `window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date());` unlike `ga('send', 'pageview');)` for index.html. which one to use – Thilak Raj Jun 29 '18 at 14:41
  • @ThilakRaj the original code is available here https://developers.google.com/analytics/devguides/collection/analyticsjs/ It looks like they updated their code with something new. I can't figure out how to implement it yet. – Ploppy Jun 29 '18 at 16:03
2

You need to convert the code to Typescript. Currently it is Javascript. The function at

function (i, s, o, g, r, a, m)

has 7 non-optional parameters, however you only supply 5 in this line:

(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga')

You'd need to make the remaining parameters optional like so:

function (i, s, o, g, r, a?, m?)

You then also need to change a different line from:

}, i[r].l = 1 * new Date();

to

}, i[r].l = 1 * <any>new Date();

The final code could look like this:

(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 * <any>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');
Luxalpa
  • 430
  • 4
  • 15