Last active
September 28, 2021 18:44
-
-
Save dtarnawsky/7bdb4df4692501c826b828246761e57c to your computer and use it in GitHub Desktop.
Google Analytics Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { HttpClient, HttpHeaders } from '@angular/common/http'; | |
import { Injectable } from '@angular/core'; | |
import { NavigationEnd } from '@angular/router'; | |
import { isDefined } from 'lib/util'; | |
let singletonInstance: AnalyticsService; | |
export const analyticsServiceSingleton: Function = (): AnalyticsService => singletonInstance; | |
export interface EventParams { | |
action: string; | |
label?: string; | |
newSession?: boolean; | |
value?: number; | |
} | |
// tslint:disable:no-console | |
@Injectable() | |
export class AnalyticsService { | |
private active: boolean = false; | |
private currentUser: string; | |
private gaCode: string; | |
private appVersion: string; | |
private clientid: string; | |
public constructor(private http: HttpClient) { | |
singletonInstance = this; | |
} | |
/** | |
* @param {string} gaCode - Google Analytics code | |
* @param {string} user - Username | |
* @param {string} uniqueId - Unique Id for the device | |
* @returns void | |
*/ | |
public SetupGoogleAnalytics(gaCode: string, user: string, uniqueId: string): void { | |
this.clientid = uniqueId; | |
this.currentUser = user; | |
this.gaCode = gaCode; | |
this.active = true; | |
} | |
public async view(title: string, path?: string): Promise<boolean> { | |
return await this.write({ t: 'pageview', dp: path, dt: title, dl: location.pathname }); | |
} | |
public setAppVersion(version?: string): void { | |
if (isDefined(version)) { | |
this.appVersion = version; | |
} | |
} | |
public async event( | |
category: string, | |
action: string, | |
label?: string, | |
value?: number, | |
newSession?: boolean | |
): Promise<boolean> { | |
return await this.write({ t: 'event', ec: category, ea: action, el: label, ev: value }); | |
} | |
public error(description: string): void { | |
this.write({ t: 'exception', exd: description, exf: 0 }); | |
console.log(`Analytics Error: ${description}`); | |
} | |
/** | |
* Tracks the page view based on Angular route taken. Formats the route title better for tracking | |
* @param {NavigationEnd} route | |
*/ | |
public viewRoute(route: NavigationEnd): string { | |
try { | |
const tabIdx: number = route.url.indexOf(':') + 1; | |
let title: string = route.url.substring(tabIdx).replace(')', ''); | |
title = decodeURIComponent(title); | |
title = this.toTitleCase(title); | |
return title; | |
} catch { | |
// Analytics are not important enough to break the app. So catch all | |
} | |
} | |
/** | |
* Set the user for Analytics | |
* @param {string} user | |
* @returns void | |
*/ | |
public setUser(user: string): void { | |
this.currentUser = user || 'guest'; | |
} | |
private toTitleCase(input: string): string { | |
return input.length === 0 | |
? '' | |
: input.replace(/\w\S*/g, (txt: string) => txt[0].toUpperCase() + txt.substr(1).toLowerCase()); | |
} | |
private async write(ob: any): Promise<boolean> { | |
if (!this.active) { | |
console.log('analytics is disabled'); | |
return false; | |
} | |
const standard: object = { | |
v: '1', | |
tid: this.gaCode, | |
cid: this.clientid, | |
uid: this.currentUser, | |
an: 'MyApplication', | |
av: this.appVersion | |
}; | |
const data: string = `${this.serialize(standard)}&${this.serialize(ob)}`; | |
const options: any = { headers: new HttpHeaders({ 'Content-Type': 'text/plain' }), responseType: 'text' }; | |
try { | |
await this.http.post('https://www.google-analytics.com/collect', data, options).toPromise(); | |
} finally { | |
return true; | |
} | |
} | |
private serialize(obj: object): string { | |
const str: Array<string> = []; | |
for (const p in obj) { | |
if (obj.hasOwnProperty(p)) { | |
if (obj[p] !== undefined) { | |
str.push(`${encodeURIComponent(p)}=${encodeURIComponent(obj[p])}`); | |
} | |
} | |
} | |
return str.join('&'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment