Skip to content

Commit 4d968ce

Browse files
committed
Merge pull request #25 from amplitude/enable_callbacks
Enable callbacks
2 parents f925b10 + 61d53da commit 4d968ce

File tree

6 files changed

+288
-30
lines changed

6 files changed

+288
-30
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## Unreleased
22

3+
* Add support for passing callback functions to logEvent
4+
5+
## 2.3.0 (September 2, 2015)
6+
37
* Add option to batch events into a single request.
48

59
## 2.2.1 (Aug 13, 2015)

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,20 @@ User IDs are automatically generated and stored in cookies if not specified.
118118
Device IDs are generated randomly, although you can define a custom device ID setting it as a configuration option or by calling:
119119

120120
amplitude.setDeviceId("CUSTOM_DEVICE_ID");
121+
122+
You can pass a callback function to logEvent, which will get called after receiving a response from the server:
123+
124+
amplitude.logEvent("EVENT_IDENTIFIER_HERE", null, callback_function);
125+
126+
The status and response from the server are passed to the callback function, which you might find useful. An example of a callback function which redirects the browser to another site after a response:
127+
128+
```javascript
129+
var callback_function = function(status, response) {
130+
if (status === 200 && response === 'success') {
131+
// do something here
132+
}
133+
window.location.replace('URL_OF_OTHER_SITE');
134+
};
135+
```
136+
137+
In the case that `optOut` is true, then no event will be logged, but the callback will be called. In the case that `batchEvents` is true, if the batch requirements `eventUploadThreshold` and `eventUploadPeriodMillis` are not met when `logEvent` is called, then no request is sent, but the callback is still called. In these cases, the callback will be called with an input status of 0 and response 'No request sent'.

amplitude.js

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -262,21 +262,24 @@ Amplitude.prototype.nextEventId = function() {
262262
return this._eventId;
263263
};
264264

265-
Amplitude.prototype._sendEventsIfReady = function() {
265+
// returns true if sendEvents called immediately
266+
Amplitude.prototype._sendEventsIfReady = function(callback) {
266267
if (this._unsentEvents.length === 0) {
267-
return;
268+
return false;
268269
}
269270

270271
if (!this.options.batchEvents) {
271-
this.sendEvents();
272-
return;
272+
this.sendEvents(callback);
273+
return true;
273274
}
274275

275276
if (this._unsentEvents.length >= this.options.eventUploadThreshold) {
276-
this.sendEvents();
277-
} else {
278-
setTimeout(this.sendEvents.bind(this), this.options.eventUploadPeriodMillis);
277+
this.sendEvents(callback);
278+
return true;
279279
}
280+
281+
setTimeout(this.sendEvents.bind(this), this.options.eventUploadPeriodMillis);
282+
return false;
280283
};
281284

282285
var _loadCookieData = function(scope) {
@@ -431,8 +434,15 @@ Amplitude.prototype.setVersionName = function(versionName) {
431434
/**
432435
* Private logEvent method. Keeps apiProperties from being publicly exposed.
433436
*/
434-
Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperties) {
437+
Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperties, callback) {
438+
if (typeof callback !== 'function') {
439+
callback = null;
440+
}
441+
435442
if (!eventType || this.options.optOut) {
443+
if (callback) {
444+
callback(0, 'No request sent');
445+
}
436446
return;
437447
}
438448
try {
@@ -501,16 +511,18 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti
501511
this.saveEvents();
502512
}
503513

504-
this._sendEventsIfReady();
514+
if (!this._sendEventsIfReady(callback) && callback) {
515+
callback(0, 'No request sent');
516+
}
505517

506518
return eventId;
507519
} catch (e) {
508520
log(e);
509521
}
510522
};
511523

512-
Amplitude.prototype.logEvent = function(eventType, eventProperties) {
513-
return this._logEvent(eventType, eventProperties);
524+
Amplitude.prototype.logEvent = function(eventType, eventProperties, callback) {
525+
return this._logEvent(eventType, eventProperties, null, callback);
514526
};
515527

516528
// Test that n is a number or a numeric value.
@@ -547,7 +559,7 @@ Amplitude.prototype.removeEvents = function (maxEventId) {
547559
this._unsentEvents = filteredEvents;
548560
};
549561

550-
Amplitude.prototype.sendEvents = function() {
562+
Amplitude.prototype.sendEvents = function(callback) {
551563
if (!this._sending && !this.options.optOut && this._unsentEvents.length > 0) {
552564
this._sending = true;
553565
var url = ('https:' === window.location.protocol ? 'https' : 'http') + '://' +
@@ -581,7 +593,9 @@ Amplitude.prototype.sendEvents = function() {
581593
}
582594

583595
// Send more events if any queued during previous send.
584-
scope._sendEventsIfReady();
596+
if (!scope._sendEventsIfReady(callback) && callback) {
597+
callback(status, response);
598+
}
585599

586600
} else if (status === 413) {
587601
//log('request too large');
@@ -593,12 +607,17 @@ Amplitude.prototype.sendEvents = function() {
593607
// The server complained about the length of the request.
594608
// Backoff and try again.
595609
scope.options.uploadBatchSize = Math.ceil(numEvents / 2);
596-
scope.sendEvents();
610+
scope.sendEvents(callback);
611+
612+
} else if (callback) { // If server turns something like a 400
613+
callback(status, response);
597614
}
598615
} catch (e) {
599616
//log('failed upload');
600617
}
601618
});
619+
} else if (callback) {
620+
callback(0, 'No request sent');
602621
}
603622
};
604623

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.js

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -150,21 +150,24 @@ Amplitude.prototype.nextEventId = function() {
150150
return this._eventId;
151151
};
152152

153-
Amplitude.prototype._sendEventsIfReady = function() {
153+
// returns true if sendEvents called immediately
154+
Amplitude.prototype._sendEventsIfReady = function(callback) {
154155
if (this._unsentEvents.length === 0) {
155-
return;
156+
return false;
156157
}
157158

158159
if (!this.options.batchEvents) {
159-
this.sendEvents();
160-
return;
160+
this.sendEvents(callback);
161+
return true;
161162
}
162163

163164
if (this._unsentEvents.length >= this.options.eventUploadThreshold) {
164-
this.sendEvents();
165-
} else {
166-
setTimeout(this.sendEvents.bind(this), this.options.eventUploadPeriodMillis);
165+
this.sendEvents(callback);
166+
return true;
167167
}
168+
169+
setTimeout(this.sendEvents.bind(this), this.options.eventUploadPeriodMillis);
170+
return false;
168171
};
169172

170173
var _loadCookieData = function(scope) {
@@ -319,8 +322,15 @@ Amplitude.prototype.setVersionName = function(versionName) {
319322
/**
320323
* Private logEvent method. Keeps apiProperties from being publicly exposed.
321324
*/
322-
Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperties) {
325+
Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperties, callback) {
326+
if (typeof callback !== 'function') {
327+
callback = null;
328+
}
329+
323330
if (!eventType || this.options.optOut) {
331+
if (callback) {
332+
callback(0, 'No request sent');
333+
}
324334
return;
325335
}
326336
try {
@@ -389,16 +399,18 @@ Amplitude.prototype._logEvent = function(eventType, eventProperties, apiProperti
389399
this.saveEvents();
390400
}
391401

392-
this._sendEventsIfReady();
402+
if (!this._sendEventsIfReady(callback) && callback) {
403+
callback(0, 'No request sent');
404+
}
393405

394406
return eventId;
395407
} catch (e) {
396408
log(e);
397409
}
398410
};
399411

400-
Amplitude.prototype.logEvent = function(eventType, eventProperties) {
401-
return this._logEvent(eventType, eventProperties);
412+
Amplitude.prototype.logEvent = function(eventType, eventProperties, callback) {
413+
return this._logEvent(eventType, eventProperties, null, callback);
402414
};
403415

404416
// Test that n is a number or a numeric value.
@@ -435,7 +447,7 @@ Amplitude.prototype.removeEvents = function (maxEventId) {
435447
this._unsentEvents = filteredEvents;
436448
};
437449

438-
Amplitude.prototype.sendEvents = function() {
450+
Amplitude.prototype.sendEvents = function(callback) {
439451
if (!this._sending && !this.options.optOut && this._unsentEvents.length > 0) {
440452
this._sending = true;
441453
var url = ('https:' === window.location.protocol ? 'https' : 'http') + '://' +
@@ -469,7 +481,9 @@ Amplitude.prototype.sendEvents = function() {
469481
}
470482

471483
// Send more events if any queued during previous send.
472-
scope._sendEventsIfReady();
484+
if (!scope._sendEventsIfReady(callback) && callback) {
485+
callback(status, response);
486+
}
473487

474488
} else if (status === 413) {
475489
//log('request too large');
@@ -481,12 +495,17 @@ Amplitude.prototype.sendEvents = function() {
481495
// The server complained about the length of the request.
482496
// Backoff and try again.
483497
scope.options.uploadBatchSize = Math.ceil(numEvents / 2);
484-
scope.sendEvents();
498+
scope.sendEvents(callback);
499+
500+
} else if (callback) { // If server turns something like a 400
501+
callback(status, response);
485502
}
486503
} catch (e) {
487504
//log('failed upload');
488505
}
489506
});
507+
} else if (callback) {
508+
callback(0, 'No request sent');
490509
}
491510
};
492511

0 commit comments

Comments
 (0)