Skip to content

Commit 4d37ba7

Browse files
committed
Merge pull request #30 from amplitude/proxy_identify_for_snippet
Proxy identify object until script loads
2 parents 6a15744 + da854fb commit 4d37ba7

File tree

11 files changed

+167
-52
lines changed

11 files changed

+167
-52
lines changed

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@ Amplitude-Javascript
88
2. On every page that uses analytics, paste the following Javascript code between the `<head>` and `</head>` tags:
99

1010
<script type="text/javascript">
11-
(function(e,t){var r=e.amplitude||{};var n=t.createElement("script");n.type="text/javascript";
12-
n.async=true;n.src="https://d24n15hnbwhuhn.cloudfront.net/libs/amplitude-2.4.1-min.gz.js";
13-
var s=t.getElementsByTagName("script")[0];s.parentNode.insertBefore(n,s);r._q=[];function a(e){
14-
r[e]=function(){r._q.push([e].concat(Array.prototype.slice.call(arguments,0)))}}var i=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties"];
15-
for(var o=0;o<i.length;o++){a(i[o])}e.amplitude=r})(window,document);
11+
(function(t,e){var n=t.amplitude||{};var r=e.createElement("script");r.type="text/javascript";
12+
r.async=true;r.src="https://d24n15hnbwhuhn.cloudfront.net/libs/amplitude-2.4.1-min.gz.js";
13+
var s=e.getElementsByTagName("script")[0];s.parentNode.insertBefore(r,s);var i=function(){
14+
this._q=[];return this};function a(t){i.prototype[t]=function(){this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));
15+
return this}}var o=["add","set","setOnce","unset"];for(var c=0;c<o.length;c++){a(o[c]);
16+
}n.Identify=i;n._q=[];function u(t){n[t]=function(){n._q.push([t].concat(Array.prototype.slice.call(arguments,0)));
17+
}}var p=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties","identify"];
18+
for(var l=0;l<p.length;l++){u(p[l])}t.amplitude=n})(window,document);
1619

1720
amplitude.init("YOUR_API_KEY_HERE");
1821
</script>

amplitude-segment-snippet.min.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
(function(e,t){var n=e.amplitude||{};n._q=[];function o(e){n[e]=function(){n._q.push([e].concat(Array.prototype.slice.call(arguments,0)));
2-
}}var r=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties"];
3-
for(var s=0;s<r.length;s++){o(r[s])}e.amplitude=n})(window,document);
1+
(function(t,e){var n=t.amplitude||{};var r=function(){this._q=[];return this};function s(t){
2+
r.prototype[t]=function(){this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));
3+
return this}}var i=["add","set","setOnce","unset"];for(var o=0;o<i.length;o++){s(i[o]);
4+
}n.Identify=r;n._q=[];function a(t){n[t]=function(){n._q.push([t].concat(Array.prototype.slice.call(arguments,0)));
5+
}}var u=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties","identify"];
6+
for(var c=0;c<u.length;c++){a(u[c])}t.amplitude=n})(window,document);

amplitude-snippet.min.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
(function(e,t){var r=e.amplitude||{};var n=t.createElement("script");n.type="text/javascript";
2-
n.async=true;n.src="https://d24n15hnbwhuhn.cloudfront.net/libs/amplitude-2.4.1-min.gz.js";
3-
var s=t.getElementsByTagName("script")[0];s.parentNode.insertBefore(n,s);r._q=[];function a(e){
4-
r[e]=function(){r._q.push([e].concat(Array.prototype.slice.call(arguments,0)))}}var i=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties"];
5-
for(var o=0;o<i.length;o++){a(i[o])}e.amplitude=r})(window,document);
1+
(function(t,e){var n=t.amplitude||{};var r=e.createElement("script");r.type="text/javascript";
2+
r.async=true;r.src="https://d24n15hnbwhuhn.cloudfront.net/libs/amplitude-2.4.1-min.gz.js";
3+
var s=e.getElementsByTagName("script")[0];s.parentNode.insertBefore(r,s);var i=function(){
4+
this._q=[];return this};function a(t){i.prototype[t]=function(){this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));
5+
return this}}var o=["add","set","setOnce","unset"];for(var c=0;c<o.length;c++){a(o[c]);
6+
}n.Identify=i;n._q=[];function u(t){n[t]=function(){n._q.push([t].concat(Array.prototype.slice.call(arguments,0)));
7+
}}var p=["init","logEvent","logRevenue","setUserId","setUserProperties","setOptOut","setVersionName","setDomain","setDeviceId","setGlobalUserProperties","identify"];
8+
for(var l=0;l<p.length;l++){u(p[l])}t.amplitude=n})(window,document);

amplitude.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,20 @@ Amplitude.prototype.setUserProperties = function(userProperties) {
464464
};
465465

466466
Amplitude.prototype.identify = function(identify) {
467-
if (identify instanceof Identify) {
467+
468+
if (type(identify) === 'object' && '_q' in identify) {
469+
var instance = new Identify();
470+
// Apply the queued commands
471+
for (var i = 0; i < identify._q.length; i++) {
472+
var fn = instance[identify._q[i][0]];
473+
if (fn && type(fn) === 'function') {
474+
fn.apply(instance, identify._q[i].slice(1));
475+
}
476+
}
477+
identify = instance;
478+
}
479+
480+
if (identify instanceof Identify && Object.keys(identify.userPropertiesOperations).length > 0) {
468481
this._logEvent(IDENTIFY_EVENT, null, null, identify.userPropertiesOperations);
469482
}
470483
};
@@ -2350,6 +2363,8 @@ module.exports = function(val){
23502363
if (val !== val) return 'nan';
23512364
if (val && val.nodeType === 1) return 'element';
23522365

2366+
if (typeof Buffer != 'undefined' && Buffer.isBuffer(val)) return 'buffer';
2367+
23532368
val = val.valueOf
23542369
? val.valueOf()
23552370
: Object.prototype.valueOf.apply(val)
@@ -3297,7 +3312,6 @@ var log = function(s) {
32973312
console.log('[Amplitude] ' + s);
32983313
};
32993314

3300-
33013315
var Identify = function() {
33023316
this.userPropertiesOperations = {};
33033317
this.properties = []; // keep track of keys that have been added

amplitude.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/amplitude-snippet.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,28 @@
66
as.src = 'https://d24n15hnbwhuhn.cloudfront.net/libs/amplitude-2.4.1-min.gz.js';
77
var s = document.getElementsByTagName('script')[0];
88
s.parentNode.insertBefore(as, s);
9+
var Identify = function() { this._q = []; return this; };
10+
function proxyIdentify(fn) {
11+
Identify.prototype[fn] = function() {
12+
this._q.push([fn].concat(Array.prototype.slice.call(arguments, 0))); return this;
13+
};
14+
}
15+
var identifyFuncs = ['add', 'set', 'setOnce', 'unset'];
16+
for (var i = 0; i < identifyFuncs.length; i++) {
17+
proxyIdentify(identifyFuncs[i]);
18+
}
19+
amplitude.Identify = Identify;
920
amplitude._q = [];
1021
function proxy(fn) {
1122
amplitude[fn] = function() {
1223
amplitude._q.push([fn].concat(Array.prototype.slice.call(arguments, 0)));
1324
};
1425
}
15-
var funcs = ["init", "logEvent", "logRevenue", "setUserId", "setUserProperties",
16-
"setOptOut", "setVersionName", "setDomain", "setDeviceId",
17-
"setGlobalUserProperties"];
18-
for (var i = 0; i < funcs.length; i++) {
19-
proxy(funcs[i]);
26+
var funcs = ['init', 'logEvent', 'logRevenue', 'setUserId', 'setUserProperties',
27+
'setOptOut', 'setVersionName', 'setDomain', 'setDeviceId',
28+
'setGlobalUserProperties', 'identify'];
29+
for (var j = 0; j < funcs.length; j++) {
30+
proxy(funcs[j]);
2031
}
2132
window.amplitude = amplitude;
2233
})(window, document);

src/amplitude.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,20 @@ Amplitude.prototype.setUserProperties = function(userProperties) {
352352
};
353353

354354
Amplitude.prototype.identify = function(identify) {
355-
if (identify instanceof Identify) {
355+
356+
if (type(identify) === 'object' && '_q' in identify) {
357+
var instance = new Identify();
358+
// Apply the queued commands
359+
for (var i = 0; i < identify._q.length; i++) {
360+
var fn = instance[identify._q[i][0]];
361+
if (fn && type(fn) === 'function') {
362+
fn.apply(instance, identify._q[i].slice(1));
363+
}
364+
}
365+
identify = instance;
366+
}
367+
368+
if (identify instanceof Identify && Object.keys(identify.userPropertiesOperations).length > 0) {
356369
this._logEvent(IDENTIFY_EVENT, null, null, identify.userPropertiesOperations);
357370
}
358371
};

src/identify.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ var log = function(s) {
1515
console.log('[Amplitude] ' + s);
1616
};
1717

18-
1918
var Identify = function() {
2019
this.userPropertiesOperations = {};
2120
this.properties = []; // keep track of keys that have been added

test/amplitude.js

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,19 +153,19 @@ describe('Amplitude', function() {
153153

154154
it('should ignore inputs that are not identify objects', function() {
155155
amplitude.identify('This is a test');
156-
assert.lengthOf(amplitude._unsentEvents, 0);
156+
assert.lengthOf(amplitude._unsentIdentifys, 0);
157157
assert.lengthOf(server.requests, 0);
158158

159159
amplitude.identify(150);
160-
assert.lengthOf(amplitude._unsentEvents, 0);
160+
assert.lengthOf(amplitude._unsentIdentifys, 0);
161161
assert.lengthOf(server.requests, 0);
162162

163163
amplitude.identify(['test']);
164-
assert.lengthOf(amplitude._unsentEvents, 0);
164+
assert.lengthOf(amplitude._unsentIdentifys, 0);
165165
assert.lengthOf(server.requests, 0);
166166

167167
amplitude.identify({'user_prop': true});
168-
assert.lengthOf(amplitude._unsentEvents, 0);
168+
assert.lengthOf(amplitude._unsentIdentifys, 0);
169169
assert.lengthOf(server.requests, 0);
170170
});
171171

@@ -197,6 +197,46 @@ describe('Amplitude', function() {
197197
});
198198
});
199199

200+
it('should ignore empty identify objects', function() {
201+
amplitude.identify(new Identify());
202+
assert.lengthOf(amplitude._unsentIdentifys, 0);
203+
assert.lengthOf(server.requests, 0);
204+
});
205+
206+
it('should ignore empty proxy identify objects', function() {
207+
amplitude.identify({'_q': {}});
208+
assert.lengthOf(amplitude._unsentIdentifys, 0);
209+
assert.lengthOf(server.requests, 0);
210+
211+
amplitude.identify({});
212+
assert.lengthOf(amplitude._unsentIdentifys, 0);
213+
assert.lengthOf(server.requests, 0);
214+
});
215+
216+
it('should generate an event from a proxy identify object', function() {
217+
var proxyObject = {'_q':[
218+
['setOnce', 'key2', 'value4'],
219+
['unset', 'key1'],
220+
['add', 'key1', 'value1'],
221+
['set', 'key2', 'value3'],
222+
['set', 'key4', 'value5'],
223+
]};
224+
amplitude.identify(proxyObject);
225+
226+
assert.lengthOf(amplitude._unsentEvents, 0);
227+
assert.lengthOf(amplitude._unsentIdentifys, 1);
228+
assert.equal(amplitude._unsentCount(), 1);
229+
assert.lengthOf(server.requests, 1);
230+
var events = JSON.parse(querystring.parse(server.requests[0].requestBody).e);
231+
assert.lengthOf(events, 1);
232+
assert.equal(events[0].event_type, '$identify');
233+
assert.deepEqual(events[0].event_properties, {});
234+
assert.deepEqual(events[0].user_properties, {
235+
'$setOnce': {'key2': 'value4'},
236+
'$unset': {'key1': '-'},
237+
'$set': {'key4': 'value5'}
238+
});
239+
});
200240
});
201241

202242
describe('logEvent', function() {

test/browser/amplitudejs.html

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,66 @@
22
<!--<script src="src/amplitude-snippet.js" type="text/javascript"></script>-->
33
<script>
44
(function(window, document) {
5-
var amplitude = window.amplitude || {};
6-
var as = document.createElement('script');
7-
as.type = 'text/javascript';
8-
as.async = true;
9-
as.src = '/amplitude.js';
10-
var s = document.getElementsByTagName('script')[0];
11-
s.parentNode.insertBefore(as, s);
12-
amplitude._q = [];
13-
function proxy(fn) {
14-
amplitude[fn] = function() {
15-
amplitude._q.push([fn].concat(Array.prototype.slice.call(arguments, 0)));
16-
};
17-
}
18-
19-
var funcs = ["init", "logEvent", "logRevenue", "setUserId", "setUserProperties", "setOptOut", "setVersionName", "setDomain", "setGlobalUserProperties"];
20-
for (var i = 0; i < funcs.length; i++) {
21-
proxy(funcs[i]);
22-
}
23-
window.amplitude = amplitude;
5+
var amplitude = window.amplitude || {};
6+
var as = document.createElement('script');
7+
as.type = 'text/javascript';
8+
as.async = true;
9+
as.src = '/amplitude.js';
10+
var s = document.getElementsByTagName('script')[0];
11+
s.parentNode.insertBefore(as, s);
12+
var Identify = function() { this._q = []; return this; };
13+
function proxyIdentify(fn) {
14+
Identify.prototype[fn] = function() {
15+
this._q.push([fn].concat(Array.prototype.slice.call(arguments, 0))); return this;
16+
};
17+
}
18+
var identifyFuncs = ['add', 'set', 'setOnce', 'unset'];
19+
for (var i = 0; i < identifyFuncs.length; i++) {
20+
proxyIdentify(identifyFuncs[i]);
21+
}
22+
amplitude.Identify = Identify;
23+
amplitude._q = [];
24+
function proxy(fn) {
25+
amplitude[fn] = function() {
26+
amplitude._q.push([fn].concat(Array.prototype.slice.call(arguments, 0)));
27+
};
28+
}
29+
var funcs = ['init', 'logEvent', 'logRevenue', 'setUserId', 'setUserProperties',
30+
'setOptOut', 'setVersionName', 'setDomain', 'setDeviceId',
31+
'setGlobalUserProperties', 'identify'];
32+
for (var j = 0; j < funcs.length; j++) {
33+
proxy(funcs[j]);
34+
}
35+
window.amplitude = amplitude;
2436
})(window, document);
2537

38+
2639
var setUserId = function() {
2740
var userId = prompt('Input userId', 'user01');
2841
amplitude.setUserId(userId);
2942
};
3043
var setEventUploadThreshold = function() {
3144
var eventUploadThreshold = parseInt(prompt('Input eventUploadThreshold', 5));
3245
amplitude.options.eventUploadThreshold = eventUploadThreshold;
33-
}
46+
};
3447
var logEvent = function() {
3548
var event = prompt('Input event type', 'clicked');
3649
amplitude.logEvent(event);
37-
}
50+
};
3851
var setCity = function() {
3952
var city = prompt('Input city', 'San Francisco, CA');
4053
amplitude.setUserProperties({city: city});
41-
}
54+
};
55+
var clickOnLinkA = function() {
56+
amplitude.logEvent('Clicked on link A', null, function() { window.location='https://www.google.com'; });
57+
};
4258
</script>
4359
<script>
4460
amplitude.init('a2dbce0e18dfe5f8e74493843ff5c053');
4561
amplitude.setVersionName('Web');
46-
//amplitude.logEvent('pageLoad');
62+
amplitude.identify(new amplitude.Identify().add('photoCount', 1));
63+
//amplitude.identify(new amplitude.Identify().add('photoCount', 1).set('gender', 'male').unset('karma'););
64+
amplitude.logEvent('pageLoad');
4765
</script>
4866
<body>
4967
<h3>Amplitude JS Test</h3>
@@ -60,5 +78,6 @@ <h3>Amplitude JS Test</h3>
6078
<li><a href="javascript:amplitude.identify(new amplitude.Identify().add('photoCount', 1));">Increment photo count</a></li>
6179
<li><a href="javascript:setCity();">Set city via setUserProperties</a></li>
6280
<li><a href="javascript:amplitude.identify(new amplitude.Identify().unset('photoCount'));">Unset photo count</a></li>
81+
<li><a href="javascript:clickOnLinkA();">Click on link A</a></li>
6382
</body>
6483
</html>

0 commit comments

Comments
 (0)