Skip to content
This repository was archived by the owner on Sep 3, 2022. It is now read-only.

Commit ca6da2f

Browse files
committed
Add analytics.ready(name, fn) function
See segmentio/analytics.js#409 This adds the ability to set a ready callback per integration. todo: * document the function behaviour (need help here on what syntax to use) * test for already readied integration
1 parent 100e85c commit ca6da2f

File tree

2 files changed

+72
-2
lines changed

2 files changed

+72
-2
lines changed

lib/analytics.js

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ function Analytics() {
4545
this.Integrations = {};
4646
this._integrations = {};
4747
this._readied = false;
48+
this._readiedIntegrations = {};
4849
this._timeout = 300;
4950
// XXX: BACKWARDS COMPATIBILITY
5051
this._user = user;
@@ -106,6 +107,7 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(settings, o
106107

107108
this._options(options);
108109
this._readied = false;
110+
this._readiedIntegrations = {};
109111

110112
// clean unknown integrations from settings
111113
var self = this;
@@ -148,8 +150,14 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(settings, o
148150
integration.page = after(2, integration.page);
149151
}
150152

153+
var integrationReady = function() {
154+
self._readiedIntegrations[integration.name] = true;
155+
self.emit(integration.name + '-ready');
156+
ready();
157+
};
158+
151159
integration.analytics = self;
152-
integration.once('ready', ready);
160+
integration.once('ready', integrationReady);
153161
try {
154162
integration.initialize();
155163
} catch (e) {
@@ -516,14 +524,58 @@ Analytics.prototype.alias = function(to, from, options, fn) {
516524
return this;
517525
};
518526

527+
/**
528+
* Register a `fn` to be fired when integrations are ready.
529+
*
530+
* If the first parameter is a function `fn`, `fn` is fired when all
531+
* integrations are ready.
532+
*
533+
* If the first parameter is a string `integration` and the second parameter is
534+
* a function `fn`, `fn` is fired when the given integration is ready.
535+
*
536+
* It is recommended that you use the latter, as the global ready callback may
537+
* not be fired if a single integration fails to load.
538+
* See https://github.com/segmentio/analytics.js/issues/409.
539+
*
540+
* @param {(Function|String)} a Callback function or integration name.
541+
* @param {Function} [b] Callback function.
542+
* @return {Analytics}
543+
*/
544+
545+
Analytics.prototype.ready = function(a, b) {
546+
if (is.fn(a)) {
547+
return this._ready(a);
548+
}
549+
return this._integrationReady(a, b);
550+
};
551+
552+
/**
553+
* Register a `fn` to be fired when the given integration is ready.
554+
*
555+
* @param {String} [name] integration name.
556+
* @param {Function} [fn] Callback function.
557+
* @return {Analytics}
558+
*/
559+
560+
Analytics.prototype._integrationReady = function(name, fn) {
561+
if (is.fn(fn)) {
562+
if (this._readiedIntegrations[name]) {
563+
nextTick(fn);
564+
} else {
565+
this.once(name + '-ready', fn);
566+
}
567+
}
568+
return this;
569+
};
570+
519571
/**
520572
* Register a `fn` to be fired when all the analytics services are ready.
521573
*
522574
* @param {Function} fn
523575
* @return {Analytics}
524576
*/
525577

526-
Analytics.prototype.ready = function(fn) {
578+
Analytics.prototype._ready = function(fn) {
527579
if (is.fn(fn)) {
528580
if (this._readied) {
529581
nextTick(fn);

test/analytics.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ describe('Analytics', function() {
6565
assert(analytics._readied === false);
6666
});
6767

68+
it('should setup a _readiedIntegrations object', function() {
69+
assert(type(analytics._readiedIntegrations) === 'object');
70+
});
71+
6872
it('should set a default timeout', function() {
6973
analytics = new Analytics();
7074
assert(analytics._timeout === 300);
@@ -172,6 +176,13 @@ describe('Analytics', function() {
172176
assert(!analytics._readied);
173177
});
174178

179+
it('should reset analytics._readiedIntegrations to {}', function() {
180+
analytics.addIntegration(Test);
181+
analytics._readiedIntegrations = { Test: true };
182+
analytics.initialize(settings);
183+
assert(!analytics._readiedIntegrations.Test);
184+
});
185+
175186
it('should add integration instance', function(done) {
176187
Test.readyOnInitialize();
177188
analytics.addIntegration(Test);
@@ -203,6 +214,13 @@ describe('Analytics', function() {
203214
analytics.initialize({ Unknown: { key: 'key' } });
204215
});
205216

217+
it('should listen on integration ready events for integration', function(done) {
218+
Test.readyOnInitialize();
219+
analytics.addIntegration(Test);
220+
analytics.ready('Test', done);
221+
analytics.initialize(settings);
222+
});
223+
206224
it('should set analytics._readied to true', function(done) {
207225
analytics.ready(function() {
208226
assert(analytics._readied);

0 commit comments

Comments
 (0)