Skip to content

Commit 39a20c5

Browse files
author
Alex Ross
committed
More refactoring
1 parent f0f0f69 commit 39a20c5

4 files changed

Lines changed: 121 additions & 37 deletions

File tree

example.html

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@
1313
<script>
1414

1515
// Provider configuration
16-
angular.module('example', ['ngSegment']).config(function (segmentProvider, segmentLoaderProvider) {
17-
console.log('segmentProvider:', segmentProvider);
18-
console.log('segmentLoaderProvider:', segmentLoaderProvider);
16+
angular.module('example', ['ngSegment']).config(function (segmentProvider) {
1917

20-
// segmentLoaderProvider.load();
18+
segmentProvider.setKey('gPsIwsLFg5XqTnpcbF1D3ZPkw41bNY6b').setAutoload(false);
19+
20+
segmentProvider.setCondition(function ($http) {
21+
return typeof $http === 'function';
22+
});
2123
});
2224

2325
// Service configuration and usage
2426
angular.module('example').controller('ExampleController', function (segment, segmentLoader) {
2527

26-
console.log('segment:', segment);
27-
console.log('segmentLoader:', segmentLoader);
28-
// segmentLoader.load();
28+
segment.track('controller test');
29+
30+
segmentLoader.load(segment.config.apiKey);
2931
});
3032

3133
angular.module('example').constant('segmentConfig', {

segment.js

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ angular.module('ngSegment').constant('segmentDefaultConfig', {
5454
script.src = ('https:' === document.location.protocol
5555
? 'https://' : 'http://')
5656
+ 'cdn.segment.com/analytics.js/v1/'
57-
+ config.apiKey + '/analytics.min.js';
57+
+ apiKey + '/analytics.min.js';
5858

5959
script.onerror = function () {
6060
console.error('Error loading Segment library.');
@@ -90,14 +90,10 @@ angular.module('ngSegment').constant('segmentDefaultConfig', {
9090

9191
var analytics = window.analytics = window.analytics || [];
9292

93-
if (analytics.initialize) {
94-
95-
}
96-
9793
// Invoked flag, to make sure the snippet
9894
// is never invoked twice.
9995
if (analytics.invoked) {
100-
console.error('Segment snippet included twice.');
96+
console.error('Segment or ngSegment included twice.');
10197
} else {
10298
analytics.invoked = true;
10399
}
@@ -118,8 +114,6 @@ angular.module('ngSegment').constant('segmentDefaultConfig', {
118114

119115
function Segment(config) {
120116

121-
console.log('Segment config:', config);
122-
123117
this.config = config;
124118

125119
// Set global analytics.js version
@@ -140,9 +134,8 @@ angular.module('ngSegment').constant('segmentDefaultConfig', {
140134
return this;
141135
};
142136

143-
// Todo
144137
this.setEvents = function (events) {
145-
138+
this.events = events;
146139
return this;
147140
};
148141

@@ -160,11 +153,37 @@ angular.module('ngSegment').constant('segmentDefaultConfig', {
160153
this.config.autoload = bool;
161154
return this;
162155
};
163-
}
164156

165-
Segment.prototype.factory = function (method) {
157+
// Creates analytics.js method stubs
158+
this.init = function () {
159+
for (var i = 0; i < this.config.methods.length; i++) {
160+
var key = this.config.methods[i];
161+
162+
// Only create analytics stub if it doesn't already exist
163+
if (!analytics[key]) {
164+
analytics[key] = analytics.factory(key);
165+
}
166+
167+
this[key] = this.factory(key);
168+
}
169+
};
170+
171+
// Checks condition before calling Segment method
172+
this.factory = function (method) {
173+
var condition = this.config.condition;
174+
return function () {
175+
176+
// If a condition has been set, only call the Segment method if it returns true
177+
if (condition && !condition(method, arguments)) {
178+
return;
179+
}
180+
181+
// No condition set, call the Segment method
182+
return analytics[method].apply(analytics, arguments);
183+
}
184+
};
185+
}
166186

167-
};
168187

169188
function SegmentProvider(segmentDefaultConfig) {
170189

@@ -173,6 +192,8 @@ angular.module('ngSegment').constant('segmentDefaultConfig', {
173192

174193
// Stores any analytics.js method calls
175194
this.queue = [];
195+
196+
// Overwrite Segment factory to queue up calls if condition has been set
176197
this.factory = function (method) {
177198
return (function () {
178199

@@ -181,11 +202,15 @@ angular.module('ngSegment').constant('segmentDefaultConfig', {
181202
if (typeof this.config.condition === 'function') {
182203
this.queue.push({ method: method, arguments: arguments });
183204
} else {
184-
205+
this[method].apply(this, arguments);
185206
}
186207
}).bind(this);
187208
};
188209

210+
// Create method stubs using overridden factory
211+
this.init();
212+
213+
// Returns segment service and optionally injected condition callback
189214
this.$get = function ($injector, segmentLoader) {
190215

191216
// Apply user-provided config constant if it exists
@@ -198,10 +223,26 @@ angular.module('ngSegment').constant('segmentDefaultConfig', {
198223
segmentLoader.load(this.config.apiKey, this.config.loadDelay);
199224
}
200225

226+
// Create dependency-injected condition
227+
if (typeof this.config.condition === 'function') {
228+
var condition = this.config.condition;
229+
this.config.condition = function (method, params) {
230+
return $injector.invoke(condition, condition, { method: method, params: params });
231+
};
232+
}
233+
201234
// Pass any provider-set configuration down to the service
202235
var segment = new Segment(this.config);
203236

204-
// Run through any segment calls that were made against the provider
237+
// Set up service method stubs
238+
segment.init();
239+
240+
// Play back any segment calls that were made against the provider
241+
this.queue.forEach(function (item) {
242+
segment[item.method].apply(segment, item.arguments);
243+
});
244+
245+
return segment;
205246
};
206247
}
207248

src/loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
script.src = ('https:' === document.location.protocol
2626
? 'https://' : 'http://')
2727
+ 'cdn.segment.com/analytics.js/v1/'
28-
+ config.apiKey + '/analytics.min.js';
28+
+ apiKey + '/analytics.min.js';
2929

3030
script.onerror = function () {
3131
console.error('Error loading Segment library.');

src/provider.js

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@
22

33
var analytics = window.analytics = window.analytics || [];
44

5-
if (analytics.initialize) {
6-
7-
}
8-
95
// Invoked flag, to make sure the snippet
106
// is never invoked twice.
117
if (analytics.invoked) {
12-
console.error('Segment snippet included twice.');
8+
console.error('Segment or ngSegment included twice.');
139
} else {
1410
analytics.invoked = true;
1511
}
@@ -30,8 +26,6 @@
3026

3127
function Segment(config) {
3228

33-
console.log('Segment config:', config);
34-
3529
this.config = config;
3630

3731
// Set global analytics.js version
@@ -52,9 +46,8 @@
5246
return this;
5347
};
5448

55-
// Todo
5649
this.setEvents = function (events) {
57-
50+
this.events = events;
5851
return this;
5952
};
6053

@@ -72,11 +65,37 @@
7265
this.config.autoload = bool;
7366
return this;
7467
};
75-
}
7668

77-
Segment.prototype.factory = function (method) {
69+
// Creates analytics.js method stubs
70+
this.init = function () {
71+
for (var i = 0; i < this.config.methods.length; i++) {
72+
var key = this.config.methods[i];
73+
74+
// Only create analytics stub if it doesn't already exist
75+
if (!analytics[key]) {
76+
analytics[key] = analytics.factory(key);
77+
}
78+
79+
this[key] = this.factory(key);
80+
}
81+
};
82+
83+
// Checks condition before calling Segment method
84+
this.factory = function (method) {
85+
var condition = this.config.condition;
86+
return function () {
87+
88+
// If a condition has been set, only call the Segment method if it returns true
89+
if (condition && !condition(method, arguments)) {
90+
return;
91+
}
92+
93+
// No condition set, call the Segment method
94+
return analytics[method].apply(analytics, arguments);
95+
}
96+
};
97+
}
7898

79-
};
8099

81100
function SegmentProvider(segmentDefaultConfig) {
82101

@@ -85,6 +104,8 @@
85104

86105
// Stores any analytics.js method calls
87106
this.queue = [];
107+
108+
// Overwrite Segment factory to queue up calls if condition has been set
88109
this.factory = function (method) {
89110
return (function () {
90111

@@ -93,11 +114,15 @@
93114
if (typeof this.config.condition === 'function') {
94115
this.queue.push({ method: method, arguments: arguments });
95116
} else {
96-
117+
this[method].apply(this, arguments);
97118
}
98119
}).bind(this);
99120
};
100121

122+
// Create method stubs using overridden factory
123+
this.init();
124+
125+
// Returns segment service and optionally injected condition callback
101126
this.$get = function ($injector, segmentLoader) {
102127

103128
// Apply user-provided config constant if it exists
@@ -110,10 +135,26 @@
110135
segmentLoader.load(this.config.apiKey, this.config.loadDelay);
111136
}
112137

138+
// Create dependency-injected condition
139+
if (typeof this.config.condition === 'function') {
140+
var condition = this.config.condition;
141+
this.config.condition = function (method, params) {
142+
return $injector.invoke(condition, condition, { method: method, params: params });
143+
};
144+
}
145+
113146
// Pass any provider-set configuration down to the service
114147
var segment = new Segment(this.config);
115148

116-
// Run through any segment calls that were made against the provider
149+
// Set up service method stubs
150+
segment.init();
151+
152+
// Play back any segment calls that were made against the provider
153+
this.queue.forEach(function (item) {
154+
segment[item.method].apply(segment, item.arguments);
155+
});
156+
157+
return segment;
117158
};
118159
}
119160

0 commit comments

Comments
 (0)