Skip to content

Commit b11d8c3

Browse files
committed
Adding analytics and tracking demo.
1 parent cc45b6c commit b11d8c3

File tree

4 files changed

+187
-2
lines changed

4 files changed

+187
-2
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ with.
1010

1111
## My JavaScript Demos - I Love JavaScript!
1212

13+
* [Tracking User Interactions And Analytics With Small Abstractions In AngularJS](https://bennadel.github.io/JavaScript-Demos/demos/tracking-user-interactions-angularjs/)
1314
* [Brute-Force Refreshing View-Data In The Background In Angular 11.0.5](https://bennadel.github.io/JavaScript-Demos/demos/load-data-in-background-angular11/dist/)
1415
* [Restoring ActiveElement Focus After A User-Interaction In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/restoring-active-element/)
1516
* [Trapping Focus Within An Element Using Tab-Key Navigation In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/focus-capture/)

demos/load-data-in-background-angular11/src/app/app.component.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,12 @@ export class AppComponent {
187187

188188
}
189189

190-
this.messages = response;
191190
this.isLoading = false;
191+
this.messages = response;
192192

193193
} catch ( error ) {
194194

195-
console.warn( "Could load load message" );
195+
console.warn( "Could not load messages." );
196196
console.error( error );
197197

198198
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
body {
3+
font-family: sans-serif ;
4+
font-size: 18px ;
5+
}
6+
7+
.items {
8+
list-style-type: none ;
9+
margin: 20px 0px 20px 0px ;
10+
padding: 0px 0px 0px 0px ;
11+
}
12+
13+
.items__item {
14+
border-bottom: 1px solid #cccccc ;
15+
margin: 10px 0px 10px 0px ;
16+
padding: 10px 0px 10px 0px ;
17+
}
18+
19+
.items a {
20+
color: red ;
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<!doctype html>
2+
<html lang="en" ng-app="Demo">
3+
<head>
4+
<meta charset="utf-8" />
5+
6+
<title>
7+
Tracking User Interactions And Analytics With Small Abstractions In AngularJS
8+
</title>
9+
10+
<link rel="stylesheet" type="text/css" href="./demo.css">
11+
</head>
12+
<body ng-controller="appController">
13+
14+
<h1>
15+
Tracking User Interactions And Analytics With Small Abstractions In AngularJS
16+
</h1>
17+
18+
<ul class="items">
19+
<li ng-repeat="friend in friends track by friend.id" class="items__item">
20+
21+
<a
22+
ng-href="#/friend/{{ friend.id }}"
23+
ng-click="trackUserInteraction( 'View friend' )">
24+
{{ friend.name }}
25+
</a>
26+
&mdash;
27+
<button ng-click="editFriend( friend )">
28+
Edit
29+
</button>
30+
<button ng-click="deleteFriend( friend )">
31+
Delete
32+
</button>
33+
34+
</li>
35+
</ul>
36+
37+
<!-- ---------------------------------------------------------------------------- -->
38+
<!-- ---------------------------------------------------------------------------- -->
39+
40+
<!-- Load scripts. -->
41+
<script type="text/javascript" src="../../vendor/jquery/3.6.0/jquery-3.6.0.min.js"></script>
42+
<script type="text/javascript" src="../../vendor/angularjs/angular-1.2.22.min.js"></script>
43+
<script type="text/javascript">
44+
45+
// Create an application module for our demo.
46+
var app = angular.module( "Demo", [] );
47+
48+
</script>
49+
<script type="text/javascript">
50+
51+
app.controller( "appController", AppController );
52+
53+
function AppController( $scope, analytics ) {
54+
55+
$scope.friends = [];
56+
57+
init();
58+
59+
// Expose the public methods.
60+
$scope.deleteFriend = deleteFriend;
61+
$scope.editFriend = editFriend;
62+
$scope.trackUserInteraction = trackUserInteraction;
63+
64+
// ---
65+
// PUBLIC METHODS.
66+
// ---
67+
68+
// I take the user to the delete confirmation form for the given friend.
69+
function deleteFriend( friend ) {
70+
71+
trackUserInteraction( "Delete friend" );
72+
73+
// TODO: Delete friend (outside the scope of demo).
74+
// ....
75+
// ....
76+
77+
}
78+
79+
80+
// I take the user to the edit form for the given friend.
81+
function editFriend( friend ) {
82+
83+
trackUserInteraction( "Edit friend" );
84+
85+
// TODO: Edit friend (outside the scope of demo).
86+
// ....
87+
// ....
88+
89+
}
90+
91+
92+
// I track the given user interaction / action.
93+
function trackUserInteraction( interaction ) {
94+
95+
// Instead of spreading this complexity throughout the component, I like
96+
// to create one (or two) methods in the component that hide this
97+
// complexity. Then, I just call these methods from within the component
98+
// controller and from within component view.
99+
analytics.track(
100+
101+
"DemoView.Action",
102+
{
103+
Action: interaction,
104+
Role: "Admin"
105+
}
106+
);
107+
108+
}
109+
110+
// ---
111+
// PRIVATE METHODS.
112+
// ---
113+
114+
// I get called once before the component is mounted.
115+
function init() {
116+
117+
trackUserInteraction( "Open" );
118+
119+
$scope.friends = [
120+
{ id: 1, name: "Kim" },
121+
{ id: 2, name: "Joe" },
122+
{ id: 3, name: "Sam" },
123+
{ id: 4, name: "Ryan" },
124+
{ id: 5, name: "Kit" }
125+
];
126+
127+
}
128+
129+
}
130+
131+
</script>
132+
<script type="text/javascript">
133+
134+
app.service( "analytics", AnalyticsFactory );
135+
136+
function AnalyticsFactory() {
137+
138+
// Expose the public methods.
139+
return({
140+
track: track
141+
});
142+
143+
// ---
144+
// PUBLIC METHODS.
145+
// ---
146+
147+
// I record the given analytics event.
148+
function track( userID, eventType, eventProperties ) {
149+
150+
console.group( "%cAnalytics Events", "font-weight: bolder ; color: dodgerblue ; text-decoration: underline ;" );
151+
console.log( "User:", userID );
152+
console.log( "Event:", eventType );
153+
console.log( "Properties:", eventProperties );
154+
console.groupEnd();
155+
156+
}
157+
158+
}
159+
160+
</script>
161+
162+
</body>
163+
</html>

0 commit comments

Comments
 (0)