lanetrotro
lanetrotro

Reputation: 357

angular and google analytics integration => ga is not a function

I'm doing an angular(4) application, but i got a problem integrating google analytics. I'm currently to add google analytics to my single page web application. But when I try to retrieve the ga function to send the new url it seems that it don't find the function.

This is the code I got:

index.hbs

<script>
    (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','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'My-key', 'auto');
</script>

app.component.ts

import { Component, OnInit } from '@angular/core';
import {NavigationEnd, Router} from "@angular/router";
import {WindowRef} from "./social/windowRef";
@Component({
    selector: 'my-app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    user: User;
    private currentRoute: string;

    constructor(private misc: MiscService, public router: Router) {
        this.router.events.subscribe(event => {
            if (event instanceof NavigationEnd) {
                console.log(event.urlAfterRedirects);
                WindowRef.get().ga('set', 'page', event.urlAfterRedirects);
                WindowRef.get().ga('send', 'pageview');
            }
        });
    }
}

windowRef.ts

export class WindowRef{
    public static get(): any{
        console.log(window);
        return window;
    }
}

I got this error: ERROR TypeError: windowRef_1.WindowRef.get(...).ga is not a function

When I do console.log(WindowRef.get()); I can see in the window the ga function but it still display the previous error when I try to use it. here and here

I don't really understand I used this method to retrieve the stripe function and it worked pretty well.

Have a good day :)

Upvotes: 10

Views: 15540

Answers (4)

Dimitri Hartt
Dimitri Hartt

Reputation: 1871

If you go to the Analytics Google Website they say this:

Copy the global site tag into the <head> section of your HTML. Or, if you use a website builder (e.g. WordPress, Shopify, etc), copy the global site tag into your website builder’s custom HTML field.

It needs to go into <head> tag.

Upvotes: 0

lanetrotro
lanetrotro

Reputation: 357

Ok, I didn't put the googleAnalytics script before the body, it was after. Now it works well. thanks to @WeissDev, it put me on the way when I saw that ga wasn't defined despite being in the window (weird). Anyway his solution works well too.

Upvotes: 2

danday74
danday74

Reputation: 56986

If @WeissDev answer don't work for you use setInterval to make sure its ready before using it.

  ngAfterViewInit() {
    this.initGoogleAnalyticsPageView()
  }

  private initGoogleAnalyticsPageView() {
    const interval = setInterval(() => {
      if ((window as any).ga && (window as any).ga.getAll) {
        this.router.events.subscribe(event => {
          const ga = (window as any).ga
          if (event instanceof NavigationEnd) {
            const tracker = ga.getAll()[0]
            tracker.set('page', event.urlAfterRedirects)
            tracker.send('pageview')
          }
        })
        clearInterval(interval)
      }
    }, 50)
  }

Upvotes: 2

WeissDev
WeissDev

Reputation: 166

I've had a similar problem trying to integrate Google Analytics into my Angular 4 App.

What did the trick for me was to move the google analytics code from the AppComponent's constructor to the ngAfterViewInit() lifecycle hook to ensure that the view is fully initialized first.

Here's the code I got:

index.html (same as you):

<script>
    (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','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'some code', 'auto');
</script>

app.component.ts:

import {AfterViewInit, Component, Inject, PLATFORM_ID} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
import {NavigationEnd, Router} from '@angular/router';

// declare google analytics
declare const ga: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {

  constructor(@Inject(PLATFORM_ID) private platformId: Object,
              private router: Router) {}


  ngAfterViewInit(): void {
    this.router.events.subscribe(event => {
      // I check for isPlatformBrowser here because I'm using Angular Universal, you may not need it
      if (event instanceof NavigationEnd && isPlatformBrowser(this.platformId)) {
        console.log(ga); // Just to make sure it's actually the ga function
        ga('set', 'page', event.urlAfterRedirects);
        ga('send', 'pageview');
      }
    });
  }
}

Let me know if this works for you as well. Have a nice day! :)

Upvotes: 15

Related Questions