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

Commit 96527ef

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 3b48c44 commit 96527ef

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

lib/analytics.js

Lines changed: 51 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;
@@ -146,8 +148,14 @@ Analytics.prototype.init = Analytics.prototype.initialize = function(settings, o
146148
integration.page = after(2, integration.page);
147149
}
148150

151+
var integrationReady = function() {
152+
self._readiedIntegrations[integration.name] = true;
153+
self.emit(integration.name + '-ready');
154+
ready();
155+
};
156+
149157
integration.analytics = self;
150-
integration.once('ready', ready);
158+
integration.once('ready', integrationReady);
151159
integration.initialize();
152160
}, integrations);
153161

@@ -496,14 +504,55 @@ Analytics.prototype.alias = function(to, from, options, fn) {
496504
return this;
497505
};
498506

507+
/**
508+
* Register a `fn` to be fired when integrations are ready.
509+
* If the first parameter is a function `fn`, `fn` is firsted when all
510+
* integrations are ready.
511+
* If the first parameter is a name and the second parameter is a function `fn`,
512+
* `fn` is fired when the given integration is ready.
513+
*
514+
* It is recommended that you use the latter, as the global ready callback may
515+
* not be fired if a single integration fails to load.
516+
* See https://github.com/segmentio/analytics.js/issues/409.
517+
*
518+
* @param {(Function|String)} a
519+
* @param {Function} b
520+
* @return {Analytics}
521+
*/
522+
523+
Analytics.prototype.ready = function(a, b) {
524+
if (is.fn(a)) {
525+
return this._ready(a);
526+
}
527+
return this._integrationReady(a, b);
528+
};
529+
530+
/**
531+
* Register a `fn` to be fired when the given analytics service is ready.
532+
*
533+
* @param {Function} fn
534+
* @return {Analytics}
535+
*/
536+
537+
Analytics.prototype._integrationReady = function(name, fn) {
538+
if (is.fn(fn)) {
539+
if (this._readiedIntegrations[name]) {
540+
nextTick(fn);
541+
} else {
542+
this.once(name + '-ready', fn);
543+
}
544+
}
545+
return this;
546+
};
547+
499548
/**
500549
* Register a `fn` to be fired when all the analytics services are ready.
501550
*
502551
* @param {Function} fn
503552
* @return {Analytics}
504553
*/
505554

506-
Analytics.prototype.ready = function(fn) {
555+
Analytics.prototype._ready = function(fn) {
507556
if (is.fn(fn)) {
508557
if (this._readied) {
509558
nextTick(fn);

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@
6969
"eslint-plugin-require-path-exists": "^1.1.5",
7070
"istanbul": "^0.4.3",
7171
"jquery": "^1.12.3",
72-
"karma": "^0.13.22",
72+
"karma": "1.3.0",
7373
"karma-browserify": "^5.0.4",
7474
"karma-chrome-launcher": "^1.0.1",
7575
"karma-coverage": "^1.0.0",
7676
"karma-junit-reporter": "^1.0.0",
77-
"karma-mocha": "^1.0.1",
77+
"karma-mocha": "1.0.1",
7878
"karma-phantomjs-launcher": "^1.0.0",
7979
"karma-sauce-launcher": "^1.0.0",
8080
"karma-spec-reporter": "0.0.26",

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 an _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);
@@ -128,6 +132,13 @@ describe('Analytics', function() {
128132
assert(!analytics._readied);
129133
});
130134

135+
it('should reset analytics._readiedIntegrations to {}', function() {
136+
analytics.addIntegration(Test);
137+
analytics._readiedIntegrations = { Test: true };
138+
analytics.initialize(settings);
139+
assert(!analytics._readiedIntegrations.Test);
140+
});
141+
131142
it('should add integration instance', function(done) {
132143
Test.readyOnInitialize();
133144
analytics.addIntegration(Test);
@@ -159,6 +170,13 @@ describe('Analytics', function() {
159170
analytics.initialize({ Unknown: { key: 'key' } });
160171
});
161172

173+
it('should listen on integration ready events for integration', function(done) {
174+
Test.readyOnInitialize();
175+
analytics.addIntegration(Test);
176+
analytics.ready('Test', done);
177+
analytics.initialize(settings);
178+
});
179+
162180
it('should set analytics._readied to true', function(done) {
163181
analytics.ready(function() {
164182
assert(analytics._readied);

0 commit comments

Comments
 (0)