Skip to content

Commit e15288b

Browse files
authored
Merge pull request #2 from expatfile/@HofmannZ/featture/init-queue
feat: ✨ queue zaraz method calls until initialised
2 parents c67e434 + 1edbdd2 commit e15288b

File tree

2 files changed

+100
-9
lines changed

2 files changed

+100
-9
lines changed

src/helpers/get-zaraz.spec.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,20 @@ declare global {
1313

1414
let windowObj: Window & typeof globalThis;
1515

16+
const logSpy = jest.spyOn(console, 'log');
17+
1618
beforeAll(() => {
1719
windowObj = window;
20+
21+
logSpy.mockImplementation();
1822
});
1923

2024
afterAll(() => {
21-
window = windowObj;
25+
Object.defineProperty(global, 'window', {
26+
value: windowObj,
27+
});
28+
29+
logSpy.mockRestore();
2230
});
2331

2432
describe('getZaraz()', () => {
@@ -36,11 +44,57 @@ describe('getZaraz()', () => {
3644
});
3745
});
3846

39-
it('should throw when zaraz does not exist on the window', () => {
47+
it('should queue events when zaraz is not defined', () => {
4048
window.zaraz = undefined;
4149

50+
// getZaraz() returns a queue.
51+
getZaraz().track('page_view', {
52+
page_location: 'https://example.com',
53+
page_path: '/',
54+
page_title: 'Home',
55+
});
56+
57+
expect(logSpy).toHaveBeenCalledWith(
58+
`Zaraz Web API is not initialized. Queueing events...`,
59+
);
60+
61+
window.zaraz = {
62+
track: trackMock,
63+
set: setMock,
64+
ecommerce: ecommerceMock,
65+
};
66+
67+
// Triggers the flush.
68+
getZaraz().track('button clicked', { userId: 'ABC-123', value: 200 });
69+
70+
expect(logSpy).toHaveBeenCalledWith(
71+
`Zaraz Web API is initialized. Flushing queue...`,
72+
);
73+
74+
// Calls the queued events.
75+
expect(trackMock).toHaveBeenCalledWith('page_view', {
76+
page_location: 'https://example.com',
77+
page_path: '/',
78+
page_title: 'Home',
79+
});
80+
81+
// Calls the actual event.
82+
expect(trackMock).toHaveBeenCalledWith('button clicked', {
83+
userId: 'ABC-123',
84+
value: 200,
85+
});
86+
87+
expect(logSpy).toHaveBeenCalledWith(`Zaraz Web API queue flushed.`);
88+
});
89+
90+
it('should throw when window is not defined', () => {
91+
// Set window to undefined.
92+
Object.defineProperty(global, 'window', {
93+
value: undefined,
94+
});
95+
4296
expect(() => getZaraz()).toThrow(
43-
`Cannot use Zaraz Web API, because window.zaraz is not defined.`,
97+
`Cannot use Zaraz Web API, because window is not defined.`,
4498
);
4599
});
46100
});

src/helpers/get-zaraz.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,49 @@
1+
type QueueItem = {
2+
method: 'track' | 'set' | 'ecommerce';
3+
arguments: unknown;
4+
};
5+
6+
let queue: QueueItem[] = [];
7+
18
/**
2-
* A utility that checks if zaraz exists on the window object. If not it throws
3-
* an error. Else returns the zaraz object.
9+
* A utility that checks if zaraz exists on the window object. If not it queues
10+
* the events until zaraz is initialized. If zaraz is initialized, it flushes
11+
* the queue.
412
*/
513
export function getZaraz() {
6-
if (typeof window !== 'undefined' && !window?.zaraz) {
7-
throw new Error(
8-
`Cannot use Zaraz Web API, because window.zaraz is not defined.`,
9-
);
14+
if (typeof window === 'undefined') {
15+
throw new Error(`Cannot use Zaraz Web API, because window is not defined.`);
16+
}
17+
18+
if (!window?.zaraz) {
19+
// eslint-disable-next-line no-console
20+
console.log(`Zaraz Web API is not initialized. Queueing events...`);
21+
22+
return {
23+
track: (...args: unknown[]) => {
24+
queue.push({ method: 'track', arguments: args });
25+
},
26+
set: (...args: unknown[]) => {
27+
queue.push({ method: 'set', arguments: args });
28+
},
29+
ecommerce: (...args: unknown[]) => {
30+
queue.push({ method: 'ecommerce', arguments: args });
31+
},
32+
};
33+
}
34+
35+
if (queue.length > 0) {
36+
// eslint-disable-next-line no-console
37+
console.log(`Zaraz Web API is initialized. Flushing queue...`);
38+
39+
queue.forEach((event) => {
40+
window.zaraz[event.method](...(event.arguments as []));
41+
});
42+
43+
// eslint-disable-next-line no-console
44+
console.log(`Zaraz Web API queue flushed.`);
45+
46+
queue = []; // Clear the queue
1047
}
1148

1249
return window.zaraz;

0 commit comments

Comments
 (0)