-
Notifications
You must be signed in to change notification settings - Fork 151
Queue calls while awaiting load
when using the NPM package
#428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Ah OK thanks for the fast reply @pooyaj! That's unfortunate. I did see that queueing in the snippet. Unfortunately that doesn't work in Typescript. It seems like this could be built into the library. For example: const [analytics] = AnalyticsBrowser.configure(...); // same options as `.load(...)`
await analytics.load(); Then Here's a solution that works for just 3 of the methods on import { Analytics, AnalyticsBrowser } from '@segment/analytics-next';
import { EventParams, PageParams, UserParams } from '@segment/analytics-next/dist/pkg/core/arguments-resolver';
type EnqueuedSegmentCall =
{
type: 'track';
args: EventParams;
} |
{
type: 'page';
args: PageParams;
} |
{
type: 'identify';
args: UserParams;
};
class Analytics {
private analytics: Analytics | undefined;
constructor() {
this.load();
}
private async load() {
const writeKey = process.env.REACT_APP_SEGMENT_WRITE_KEY;
const cdnURL = process.env.REACT_APP_SEGMENT_CDN_PROXY;
if (!writeKey) throw new Error('Segment Write Key Cannot Be Undefined');
if (!cdnURL) throw new Error('Segment CDN URL Cannot Be Undefined');
const [analytics] = await AnalyticsBrowser.load({ writeKey, cdnURL });
this.analytics = analytics;
this.flushQueue();
}
private enqueuedCalls: EnqueuedSegmentCall[] = [];
private flushQueue() {
this.enqueuedCalls.forEach((call) => {
switch (call.type) {
case 'track':
return this.track(...call.args);
case 'page':
return this.page(...call.args);
case 'identify':
return this.identify(...call.args);
}
});
this.enqueuedCalls = [];
}
track(...args: EventParams) {
if (!this.analytics) {
this.enqueuedCalls.push({ type: 'track', args: args });
return;
}
this.analytics.track(...args);
}
page(...args: PageParams) {
if (!this.analytics) {
this.enqueuedCalls.push({ type: 'page', args: args });
return;
}
this.analytics?.page(...args);
}
identify(...args: UserParams) {
if (!this.analytics) {
this.enqueuedCalls.push({ type: 'identify', args: args });
return;
}
this.analytics?.identify(...args);
}
}
export default new Analytics(); This then gives us this very clean interface throughout our calling code: import analytics from '@analytics/analytics';
analytics.track(...);
analytics.page(...);
analytics.identify(...); |
@tsheaff your solution looks great 🙌 I think we will build queuing mechanism for our npm package in near future as well so you don't have to wrap the library/import internal types |
Ah OK great. I'll keep track of this issue until that's done. Can you leave this open and track that PR against this issue? I've renamed it for more clarity. |
I think it will require a new interface as I mentioned as well so that you can get your |
load
when using the NPM package
@tsheaff this is an awesome suggestion! We're actively working on this feature, I will tag you in the PR. |
Feature merged in #436, should be available next release. |
Thank you so much for implementing this! You saved us a ton of work! It worked great! |
Uh oh!
There was an error while loading. Please reload this page.
I'm loading from NPM rather than through the snippet.
I may be misunderatanding how
AnalyticsBrowser.load()
works, and I see reference in the docs to the library enqueuing calls before the script loads, but according to the example in the README, theanalytics
instance is optional untilawait AnalyticsBrowser.load({ ... })
is completed. This means anyanalytics?.track(...)
,analytics?.identify(...)
etc. will be no-ops while awaiting. This seems quite bad since there will now be race conditions between our initial events like page views, versus the time for theAnalyticsBrowser.load
to complete.Am I misunderstanding things? How can I get all of my calls to
analytics
to work, even those that run immediately after callingawait AnalyticsBrowser.load
but before that response has come back? Do I have to wrap the lib and implement enqueing myself?cc @chrisradek @pooyaj @danieljackins
The text was updated successfully, but these errors were encountered: