Reputation: 357
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
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
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
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
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