Skip to content

Commit

Permalink
fix: wait for capture to load before sendEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
convell authored and Paul Marshall committed Mar 14, 2024
1 parent 3561374 commit d815934
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 35 deletions.
1 change: 0 additions & 1 deletion src/api/QuantumMetric.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ describe('Quantum Metric', () => {
identityApi: mockIdentityApi,
capture: mockQuantumMetricAPI,
});

const searchContext = {
routeRef: 'unknown',
pluginId: 'search',
Expand Down
99 changes: 65 additions & 34 deletions src/api/QuantumMetric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export type QuantumMetricAPI = {
* @public
*/
export class QuantumMetric implements AnalyticsApi, NewAnalyticsApi {
private readonly capture: QuantumMetricAPI = {} as QuantumMetricAPI;
private capture: QuantumMetricAPI = {} as QuantumMetricAPI;
private test: boolean = false;
private debug: boolean = false;
private quantumInstalled: boolean = false;
Expand Down Expand Up @@ -82,72 +82,87 @@ export class QuantumMetric implements AnalyticsApi, NewAnalyticsApi {
this.quantumInstalled = true;
}

if (src) {
if (this.debug) console.debug(`Fetching Quantum Metric API from ${src}`);
this.installQuantum(async, src);
if (this.debug) console.debug('Quantum Metric has been fetched');
if (options.capture) {
this.capture = options.capture;
this.quantumInstalled = true;
}

this.capture =
options.capture || ((window as any).QuantumMetricAPI as QuantumMetricAPI);
if (this.debug) console.debug('Set class capture member variable');
this.installQuantum(async, src).then(() => {
this.capture =
options.capture ||
((window as any).QuantumMetricAPI as QuantumMetricAPI);

this.setIdentity(options.identityApi);
});

this.setEventsMapping(events);
this.setEventTransforms(options.eventTransforms);
this.setGlobalAttributes(options.qmConfig.globalAttributes);
}

private setEventTransforms(eventTransforms?: Record<string, Transformer>) {
if (eventTransforms) {
this.eventTransforms = eventTransforms;
}
}

if (options.identityApi) {
private setIdentity(identityApi?: IdentityApi) {
if (identityApi) {
if (this.debug)
console.debug('Identity API provided; Identifying user by email');

// TODO wait for quantum to load
console.debug('Quantum API loaded');
options.identityApi.getProfileInfo().then((profile) => {
identityApi.getProfileInfo().then((profile) => {
if (profile?.email) this.capture?.identifyUser(profile.email);
});
}
}

if (events) {
this.eventsMapping = events.reduce(
private setGlobalAttributes(globalAttributes: QMConfig['globalAttributes']) {
if (globalAttributes) {
this.globalAttributes = globalAttributes.reduce(
(prev, curr) => {
prev[curr.name] = curr.id;
prev[curr.name] = curr.value;
return prev;
},
{} as Record<string, number>,
{} as Record<string, string | boolean | number>,
);
if (this.debug)
console.debug(
`Event mapping configured: ${JSON.stringify(this.eventsMapping)}`,
`Global attributes configured: ${JSON.stringify(
this.globalAttributes,
)}`,
);
} else if (!events && debug) {
console.debug(
'Events mapping not passed in, OOTB events will not be sent to Quantum Metric',
);
}

if (options.eventTransforms) {
this.eventTransforms = options.eventTransforms;
}
}

if (options.qmConfig.globalAttributes) {
this.globalAttributes = options.qmConfig.globalAttributes.reduce(
private setEventsMapping(events: QMConfig['events']) {
if (events) {
this.eventsMapping = events.reduce(
(prev, curr) => {
prev[curr.name] = curr.value;
prev[curr.name] = curr.id;
return prev;
},
{} as Record<string, string | boolean | number>,
{} as Record<string, number>,
);
if (this.debug)
console.debug(
`Global attributes configured: ${JSON.stringify(
this.globalAttributes,
)}`,
`Event mapping configured: ${JSON.stringify(this.eventsMapping)}`,
);
} else if (!events && this.debug) {
console.debug(
'Events mapping not passed in, OOTB events will not be sent to Quantum Metric',
);
}
}

private installQuantum(async: boolean, src: string) {
private async installQuantum(async: boolean, src: string) {
if (this.quantumInstalled) {
if (this.debug)
console.debug(`Quantum Metric API already on page; Skipping install`);
return;
}

this.quantumInstalled = true;
if (this.debug) console.debug(`Fetching Quantum Metric API from ${src}`);
const qtm = document.createElement('script');
qtm.type = 'text/javascript';
qtm.async = async;
Expand All @@ -158,6 +173,14 @@ export class QuantumMetric implements AnalyticsApi, NewAnalyticsApi {
if (d.parentNode) {
d.parentNode.insertBefore(qtm, d);
}

await new Promise((resolve) => {
qtm.addEventListener('load', () => {
if (this.debug) console.debug('Quantum Metric has been loaded');
this.quantumInstalled = true;
resolve('');
});
});
}

/*
Expand Down Expand Up @@ -244,6 +267,14 @@ export class QuantumMetric implements AnalyticsApi, NewAnalyticsApi {
* captureEvent handles sending events to Quantum Metric via the fetched window API
*/
captureEvent(event: AnalyticsEvent | NewAnalyticsEvent) {
if (!this.quantumInstalled) {
if (this.debug)
console.debug(
'Analytics Event sent before Quantum Metric was installed; Returning',
);
return;
}

if (this.test) {
console.log(`Test Event received: ${JSON.stringify(event)}; Returning`);
return;
Expand Down

0 comments on commit d815934

Please sign in to comment.