Skip to content

Commit 44574bc

Browse files
authoredAug 24, 2021
fix(sendEvent): split > 20 objects in multiple calls (#4841)
* fix(sendEvent): split > 20 objects in multiple calls DX-2379 * bindEvent allows multiple now too
1 parent 047acd0 commit 44574bc

File tree

7 files changed

+381
-182
lines changed

7 files changed

+381
-182
lines changed
 

‎src/connectors/hits/__tests__/connectHits-test.ts

+39-35
Original file line numberDiff line numberDiff line change
@@ -846,26 +846,28 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
846846
expect(payload.startsWith('data-insights-event=')).toBe(true);
847847
expect(
848848
deserializePayload(payload.substr('data-insights-event='.length))
849-
).toEqual({
850-
eventType: 'click',
851-
hits: [
852-
{
853-
__position: 0,
854-
__queryID: 'test-query-id',
855-
fake: 'data',
856-
objectID: '1',
849+
).toEqual([
850+
{
851+
eventType: 'click',
852+
hits: [
853+
{
854+
__position: 0,
855+
__queryID: 'test-query-id',
856+
fake: 'data',
857+
objectID: '1',
858+
},
859+
],
860+
insightsMethod: 'clickedObjectIDsAfterSearch',
861+
payload: {
862+
eventName: 'Product Added',
863+
index: '',
864+
objectIDs: ['1'],
865+
positions: [0],
866+
queryID: 'test-query-id',
857867
},
858-
],
859-
insightsMethod: 'clickedObjectIDsAfterSearch',
860-
payload: {
861-
eventName: 'Product Added',
862-
index: '',
863-
objectIDs: ['1'],
864-
positions: [0],
865-
queryID: 'test-query-id',
868+
widgetType: 'ais.hits',
866869
},
867-
widgetType: 'ais.hits',
868-
});
870+
]);
869871
});
870872

871873
it('returns a payload for conversion event', () => {
@@ -876,25 +878,27 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
876878
expect(payload.startsWith('data-insights-event=')).toBe(true);
877879
expect(
878880
deserializePayload(payload.substr('data-insights-event='.length))
879-
).toEqual({
880-
eventType: 'conversion',
881-
hits: [
882-
{
883-
__position: 1,
884-
__queryID: 'test-query-id',
885-
objectID: '2',
886-
sample: 'infos',
881+
).toEqual([
882+
{
883+
eventType: 'conversion',
884+
hits: [
885+
{
886+
__position: 1,
887+
__queryID: 'test-query-id',
888+
objectID: '2',
889+
sample: 'infos',
890+
},
891+
],
892+
insightsMethod: 'convertedObjectIDsAfterSearch',
893+
payload: {
894+
eventName: 'Product Ordered',
895+
index: '',
896+
objectIDs: ['2'],
897+
queryID: 'test-query-id',
887898
},
888-
],
889-
insightsMethod: 'convertedObjectIDsAfterSearch',
890-
payload: {
891-
eventName: 'Product Ordered',
892-
index: '',
893-
objectIDs: ['2'],
894-
queryID: 'test-query-id',
899+
widgetType: 'ais.hits',
895900
},
896-
widgetType: 'ais.hits',
897-
});
901+
]);
898902
});
899903
});
900904
});

‎src/connectors/infinite-hits/__tests__/connectInfiniteHits-test.ts

+39-35
Original file line numberDiff line numberDiff line change
@@ -1468,26 +1468,28 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/infinite-hi
14681468
expect(payload.startsWith('data-insights-event=')).toBe(true);
14691469
expect(
14701470
deserializePayload(payload.substr('data-insights-event='.length))
1471-
).toEqual({
1472-
eventType: 'click',
1473-
hits: [
1474-
{
1475-
__position: 0,
1476-
__queryID: 'test-query-id',
1477-
fake: 'data',
1478-
objectID: '1',
1471+
).toEqual([
1472+
{
1473+
eventType: 'click',
1474+
hits: [
1475+
{
1476+
__position: 0,
1477+
__queryID: 'test-query-id',
1478+
fake: 'data',
1479+
objectID: '1',
1480+
},
1481+
],
1482+
insightsMethod: 'clickedObjectIDsAfterSearch',
1483+
payload: {
1484+
eventName: 'Product Added',
1485+
index: '',
1486+
objectIDs: ['1'],
1487+
positions: [0],
1488+
queryID: 'test-query-id',
14791489
},
1480-
],
1481-
insightsMethod: 'clickedObjectIDsAfterSearch',
1482-
payload: {
1483-
eventName: 'Product Added',
1484-
index: '',
1485-
objectIDs: ['1'],
1486-
positions: [0],
1487-
queryID: 'test-query-id',
1490+
widgetType: 'ais.infiniteHits',
14881491
},
1489-
widgetType: 'ais.infiniteHits',
1490-
});
1492+
]);
14911493
});
14921494

14931495
it('returns a payload for conversion event', () => {
@@ -1498,25 +1500,27 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/infinite-hi
14981500
expect(payload.startsWith('data-insights-event=')).toBe(true);
14991501
expect(
15001502
deserializePayload(payload.substr('data-insights-event='.length))
1501-
).toEqual({
1502-
eventType: 'conversion',
1503-
hits: [
1504-
{
1505-
__position: 1,
1506-
__queryID: 'test-query-id',
1507-
objectID: '2',
1508-
sample: 'infos',
1503+
).toEqual([
1504+
{
1505+
eventType: 'conversion',
1506+
hits: [
1507+
{
1508+
__position: 1,
1509+
__queryID: 'test-query-id',
1510+
objectID: '2',
1511+
sample: 'infos',
1512+
},
1513+
],
1514+
insightsMethod: 'convertedObjectIDsAfterSearch',
1515+
payload: {
1516+
eventName: 'Product Ordered',
1517+
index: '',
1518+
objectIDs: ['2'],
1519+
queryID: 'test-query-id',
15091520
},
1510-
],
1511-
insightsMethod: 'convertedObjectIDsAfterSearch',
1512-
payload: {
1513-
eventName: 'Product Ordered',
1514-
index: '',
1515-
objectIDs: ['2'],
1516-
queryID: 'test-query-id',
1521+
widgetType: 'ais.infiniteHits',
15171522
},
1518-
widgetType: 'ais.infiniteHits',
1519-
});
1523+
]);
15201524
});
15211525
});
15221526
});

‎src/helpers/insights.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export function readDataAttributes(domElement: HTMLElement): {
1818
}
1919

2020
try {
21-
const payload: Partial<InsightsClientPayload> =
22-
deserializePayload(serializedPayload);
21+
const payload =
22+
deserializePayload<Partial<InsightsClientPayload>>(serializedPayload);
2323
return { method, payload };
2424
} catch (error) {
2525
throw new Error(

‎src/lib/insights/listener.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ const findInsightsTarget = (
2727
return element;
2828
};
2929

30-
type ParseInsightsEvent = (element: HTMLElement) => InsightsEvent;
31-
32-
const parseInsightsEvent: ParseInsightsEvent = (element) => {
30+
const parseInsightsEvent = (element: HTMLElement): InsightsEvent[] => {
3331
const serializedPayload = element.getAttribute('data-insights-event');
3432

3533
if (typeof serializedPayload !== 'string') {
@@ -39,7 +37,7 @@ const parseInsightsEvent: ParseInsightsEvent = (element) => {
3937
}
4038

4139
try {
42-
return deserializePayload(serializedPayload) as InsightsEvent;
40+
return deserializePayload(serializedPayload);
4341
} catch (error) {
4442
throw new Error(
4543
'The insights middleware was unable to parse `data-insights-event`.'
@@ -59,7 +57,8 @@ const insightsListener = (BaseComponent: any) => {
5957
);
6058
if (targetWithEvent) {
6159
const payload = parseInsightsEvent(targetWithEvent);
62-
props.sendEvent(payload);
60+
61+
payload.forEach((single) => props.sendEvent!(single));
6362
}
6463
}
6564

‎src/lib/utils/__tests__/createSendEventForHits-test.ts

+215-45
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,15 @@ import {
66
import { deserializePayload } from '../../utils';
77
import type { EscapedHits } from '../../../types';
88

9-
const createTestEnvironment = () => {
9+
const createTestEnvironment = ({ nbHits = 2 }: { nbHits?: number } = {}) => {
1010
const instantSearchInstance = createInstantSearch();
1111
const index = 'testIndex';
1212
const widgetType = 'ais.testWidget';
13-
const hits = [
14-
{
15-
objectID: 'obj0',
16-
__position: 0,
17-
__queryID: 'test-query-id',
18-
},
19-
{
20-
objectID: 'obj1',
21-
__position: 1,
22-
__queryID: 'test-query-id',
23-
},
24-
];
13+
const hits = Array.from({ length: nbHits }, (_, i) => ({
14+
__position: i,
15+
__queryID: 'test-query-id',
16+
objectID: `obj${i}`,
17+
}));
2518
const sendEvent = createSendEventForHits({
2619
instantSearchInstance,
2720
index,
@@ -163,6 +156,44 @@ describe('createSendEventForHits', () => {
163156
});
164157
});
165158

159+
it('sends view event with more than 20 hits', () => {
160+
const { sendEvent, instantSearchInstance, hits } = createTestEnvironment({
161+
nbHits: 21,
162+
});
163+
sendEvent('view', hits);
164+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledTimes(2);
165+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledWith({
166+
eventType: 'view',
167+
hits: Array.from({ length: 20 }, (_, i) => ({
168+
__position: i,
169+
__queryID: 'test-query-id',
170+
objectID: `obj${i}`,
171+
})),
172+
insightsMethod: 'viewedObjectIDs',
173+
payload: {
174+
eventName: 'Hits Viewed',
175+
index: 'testIndex',
176+
objectIDs: Array.from({ length: 20 }, (_, i) => `obj${i}`),
177+
},
178+
widgetType: 'ais.testWidget',
179+
});
180+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledWith({
181+
eventType: 'view',
182+
hits: Array.from({ length: 1 }, (_, i) => ({
183+
__position: 20 + i,
184+
__queryID: 'test-query-id',
185+
objectID: `obj${20 + i}`,
186+
})),
187+
insightsMethod: 'viewedObjectIDs',
188+
payload: {
189+
eventName: 'Hits Viewed',
190+
index: 'testIndex',
191+
objectIDs: Array.from({ length: 1 }, (_, i) => `obj${20 + i}`),
192+
},
193+
widgetType: 'ais.testWidget',
194+
});
195+
});
196+
166197
it('sends click event', () => {
167198
const { sendEvent, instantSearchInstance, hits } = createTestEnvironment();
168199
sendEvent('click', hits[0], 'Product Clicked');
@@ -188,6 +219,52 @@ describe('createSendEventForHits', () => {
188219
});
189220
});
190221

222+
it('sends click event with more than 20 hits', () => {
223+
const { sendEvent, instantSearchInstance, hits } = createTestEnvironment({
224+
nbHits: 21,
225+
});
226+
sendEvent('click', hits, 'Product Clicked');
227+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledTimes(2);
228+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledWith({
229+
eventType: 'click',
230+
hits: Array.from({ length: 20 }, (_, i) => {
231+
return {
232+
__position: i,
233+
__queryID: 'test-query-id',
234+
objectID: `obj${i}`,
235+
};
236+
}),
237+
insightsMethod: 'clickedObjectIDsAfterSearch',
238+
payload: {
239+
eventName: 'Product Clicked',
240+
index: 'testIndex',
241+
objectIDs: Array.from({ length: 20 }, (_, i) => `obj${i}`),
242+
positions: Array.from({ length: 20 }, (_, i) => i),
243+
queryID: 'test-query-id',
244+
},
245+
widgetType: 'ais.testWidget',
246+
});
247+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledWith({
248+
eventType: 'click',
249+
hits: [
250+
{
251+
__position: 20,
252+
__queryID: 'test-query-id',
253+
objectID: 'obj20',
254+
},
255+
],
256+
insightsMethod: 'clickedObjectIDsAfterSearch',
257+
payload: {
258+
eventName: 'Product Clicked',
259+
index: 'testIndex',
260+
objectIDs: ['obj20'],
261+
positions: [20],
262+
queryID: 'test-query-id',
263+
},
264+
widgetType: 'ais.testWidget',
265+
});
266+
});
267+
191268
it('sends conversion event', () => {
192269
const { sendEvent, instantSearchInstance, hits } = createTestEnvironment();
193270
sendEvent('conversion', hits[0], 'Product Ordered');
@@ -212,6 +289,50 @@ describe('createSendEventForHits', () => {
212289
});
213290
});
214291

292+
it('sends conversion event with more than 20 hits', () => {
293+
const { sendEvent, instantSearchInstance, hits } = createTestEnvironment({
294+
nbHits: 21,
295+
});
296+
sendEvent('conversion', hits, 'Product Ordered');
297+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledTimes(2);
298+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledWith({
299+
eventType: 'conversion',
300+
hits: Array.from({ length: 20 }, (_, i) => {
301+
return {
302+
__position: i,
303+
__queryID: 'test-query-id',
304+
objectID: `obj${i}`,
305+
};
306+
}),
307+
insightsMethod: 'convertedObjectIDsAfterSearch',
308+
payload: {
309+
eventName: 'Product Ordered',
310+
index: 'testIndex',
311+
objectIDs: Array.from({ length: 20 }, (_, i) => `obj${i}`),
312+
queryID: 'test-query-id',
313+
},
314+
widgetType: 'ais.testWidget',
315+
});
316+
expect(instantSearchInstance.sendEventToInsights).toHaveBeenCalledWith({
317+
eventType: 'conversion',
318+
hits: [
319+
{
320+
__position: 20,
321+
__queryID: 'test-query-id',
322+
objectID: 'obj20',
323+
},
324+
],
325+
insightsMethod: 'convertedObjectIDsAfterSearch',
326+
payload: {
327+
eventName: 'Product Ordered',
328+
index: 'testIndex',
329+
objectIDs: ['obj20'],
330+
queryID: 'test-query-id',
331+
},
332+
widgetType: 'ais.testWidget',
333+
});
334+
});
335+
215336
it('sends custom event', () => {
216337
const { sendEvent, instantSearchInstance } = createTestEnvironment();
217338
sendEvent({
@@ -268,49 +389,98 @@ describe('createBindEventForHits', () => {
268389
const parsedPayload = parsePayload(
269390
bindEvent('click', hits[0], 'Product Clicked')
270391
);
271-
expect(parsedPayload).toEqual({
272-
eventType: 'click',
273-
hits: [
274-
{
275-
__position: 0,
276-
__queryID: 'test-query-id',
277-
objectID: 'obj0',
392+
expect(parsedPayload).toEqual([
393+
{
394+
eventType: 'click',
395+
hits: [
396+
{
397+
__position: 0,
398+
__queryID: 'test-query-id',
399+
objectID: 'obj0',
400+
},
401+
],
402+
insightsMethod: 'clickedObjectIDsAfterSearch',
403+
payload: {
404+
eventName: 'Product Clicked',
405+
index: 'testIndex',
406+
objectIDs: ['obj0'],
407+
positions: [0],
408+
queryID: 'test-query-id',
278409
},
279-
],
280-
insightsMethod: 'clickedObjectIDsAfterSearch',
281-
payload: {
282-
eventName: 'Product Clicked',
283-
index: 'testIndex',
284-
objectIDs: ['obj0'],
285-
positions: [0],
286-
queryID: 'test-query-id',
410+
widgetType: 'ais.testWidget',
287411
},
288-
widgetType: 'ais.testWidget',
289-
});
412+
]);
290413
});
291414

292415
it('returns a payload for conversion event', () => {
293416
const { bindEvent, hits } = createTestEnvironment();
294417
const parsedPayload = parsePayload(
295418
bindEvent('conversion', hits[0], 'Product Ordered')
296419
);
297-
expect(parsedPayload).toEqual({
298-
eventType: 'conversion',
299-
hits: [
300-
{
301-
__position: 0,
420+
expect(parsedPayload).toEqual([
421+
{
422+
eventType: 'conversion',
423+
hits: [
424+
{
425+
__position: 0,
426+
__queryID: 'test-query-id',
427+
objectID: 'obj0',
428+
},
429+
],
430+
insightsMethod: 'convertedObjectIDsAfterSearch',
431+
payload: {
432+
eventName: 'Product Ordered',
433+
index: 'testIndex',
434+
objectIDs: ['obj0'],
435+
queryID: 'test-query-id',
436+
},
437+
widgetType: 'ais.testWidget',
438+
},
439+
]);
440+
});
441+
442+
it('splits a payload for > 20 hits', () => {
443+
const { bindEvent, hits } = createTestEnvironment({ nbHits: 21 });
444+
const parsedPayload = parsePayload(
445+
bindEvent('click', hits, 'Product Clicked')
446+
);
447+
expect(parsedPayload).toEqual([
448+
{
449+
eventType: 'click',
450+
hits: Array.from({ length: 20 }, (_, i) => ({
451+
__position: i,
302452
__queryID: 'test-query-id',
303-
objectID: 'obj0',
453+
objectID: `obj${i}`,
454+
})),
455+
insightsMethod: 'clickedObjectIDsAfterSearch',
456+
payload: {
457+
eventName: 'Product Clicked',
458+
index: 'testIndex',
459+
objectIDs: Array.from({ length: 20 }, (_, i) => `obj${i}`),
460+
positions: Array.from({ length: 20 }, (_, i) => i),
461+
queryID: 'test-query-id',
304462
},
305-
],
306-
insightsMethod: 'convertedObjectIDsAfterSearch',
307-
payload: {
308-
eventName: 'Product Ordered',
309-
index: 'testIndex',
310-
objectIDs: ['obj0'],
311-
queryID: 'test-query-id',
463+
widgetType: 'ais.testWidget',
312464
},
313-
widgetType: 'ais.testWidget',
314-
});
465+
{
466+
eventType: 'click',
467+
hits: [
468+
{
469+
__position: 20,
470+
__queryID: 'test-query-id',
471+
objectID: 'obj20',
472+
},
473+
],
474+
insightsMethod: 'clickedObjectIDsAfterSearch',
475+
payload: {
476+
eventName: 'Product Clicked',
477+
index: 'testIndex',
478+
objectIDs: ['obj20'],
479+
positions: [20],
480+
queryID: 'test-query-id',
481+
},
482+
widgetType: 'ais.testWidget',
483+
},
484+
]);
315485
});
316486
});

‎src/lib/utils/createSendEventForHits.ts

+79-57
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,28 @@ type BuiltInBindEventForHits = (
1818
type CustomBindEventForHits = (customPayload: any) => string;
1919
export type BindEventForHits = BuiltInBindEventForHits & CustomBindEventForHits;
2020

21-
type BuildPayload = (options: {
22-
widgetType: string;
23-
index: string;
24-
methodName: 'sendEvent' | 'bindEvent';
25-
args: any[];
26-
}) => InsightsEvent | null;
21+
function chunk<TItem>(arr: TItem[], chunkSize: number = 20): TItem[][] {
22+
const chunks: TItem[][] = [];
23+
for (let i = 0; i < Math.ceil(arr.length / chunkSize); i++) {
24+
chunks.push(arr.slice(i * chunkSize, (i + 1) * chunkSize));
25+
}
26+
return chunks;
27+
}
2728

28-
const buildPayload: BuildPayload = ({
29+
const buildPayloads = ({
2930
index,
3031
widgetType,
3132
methodName,
3233
args,
33-
}) => {
34+
}: {
35+
widgetType: string;
36+
index: string;
37+
methodName: 'sendEvent' | 'bindEvent';
38+
args: any[];
39+
}): InsightsEvent[] => {
40+
// when there's only one argument, that means it's custom
3441
if (args.length === 1 && typeof args[0] === 'object') {
35-
return args[0];
42+
return [args[0]];
3643
}
3744
const eventType: string = args[0];
3845
const hits: Hit | Hits | EscapedHits = args[1];
@@ -45,7 +52,7 @@ const buildPayload: BuildPayload = ({
4552
`
4653
);
4754
} else {
48-
return null;
55+
return [];
4956
}
5057
}
5158
if ((eventType === 'click' || eventType === 'conversion') && !eventName) {
@@ -58,65 +65,76 @@ const buildPayload: BuildPayload = ({
5865
`
5966
);
6067
} else {
61-
return null;
68+
return [];
6269
}
6370
}
6471
const hitsArray: Hits = Array.isArray(hits)
6572
? removeEscapedFromHits(hits)
6673
: [hits];
6774

6875
if (hitsArray.length === 0) {
69-
return null;
76+
return [];
7077
}
7178
const queryID = hitsArray[0].__queryID;
72-
const objectIDs = hitsArray.map((hit) => hit.objectID);
73-
const positions = hitsArray.map((hit) => hit.__position);
79+
const hitsChunks = chunk(hitsArray);
80+
const objectIDsByChunk = hitsChunks.map((batch) =>
81+
batch.map((hit) => hit.objectID)
82+
);
83+
const positionsByChunk = hitsChunks.map((batch) =>
84+
batch.map((hit) => hit.__position)
85+
);
7486

7587
if (eventType === 'view') {
76-
return {
77-
insightsMethod: 'viewedObjectIDs',
78-
widgetType,
79-
eventType,
80-
payload: {
81-
eventName: eventName || 'Hits Viewed',
82-
index,
83-
objectIDs,
84-
},
85-
hits: hitsArray,
86-
};
88+
return hitsChunks.map((batch, i) => {
89+
return {
90+
insightsMethod: 'viewedObjectIDs',
91+
widgetType,
92+
eventType,
93+
payload: {
94+
eventName: eventName || 'Hits Viewed',
95+
index,
96+
objectIDs: objectIDsByChunk[i],
97+
},
98+
hits: batch,
99+
};
100+
});
87101
} else if (eventType === 'click') {
88-
return {
89-
insightsMethod: 'clickedObjectIDsAfterSearch',
90-
widgetType,
91-
eventType,
92-
payload: {
93-
eventName,
94-
index,
95-
queryID,
96-
objectIDs,
97-
positions,
98-
},
99-
hits: hitsArray,
100-
};
102+
return hitsChunks.map((batch, i) => {
103+
return {
104+
insightsMethod: 'clickedObjectIDsAfterSearch',
105+
widgetType,
106+
eventType,
107+
payload: {
108+
eventName,
109+
index,
110+
queryID,
111+
objectIDs: objectIDsByChunk[i],
112+
positions: positionsByChunk[i],
113+
},
114+
hits: batch,
115+
};
116+
});
101117
} else if (eventType === 'conversion') {
102-
return {
103-
insightsMethod: 'convertedObjectIDsAfterSearch',
104-
widgetType,
105-
eventType,
106-
payload: {
107-
eventName,
108-
index,
109-
queryID,
110-
objectIDs,
111-
},
112-
hits: hitsArray,
113-
};
118+
return hitsChunks.map((batch, i) => {
119+
return {
120+
insightsMethod: 'convertedObjectIDsAfterSearch',
121+
widgetType,
122+
eventType,
123+
payload: {
124+
eventName,
125+
index,
126+
queryID,
127+
objectIDs: objectIDsByChunk[i],
128+
},
129+
hits: batch,
130+
};
131+
});
114132
} else if (__DEV__) {
115133
throw new Error(`eventType("${eventType}") is not supported.
116134
If you want to send a custom payload, you can pass one object: ${methodName}(customPayload);
117135
`);
118136
} else {
119-
return null;
137+
return [];
120138
}
121139
};
122140

@@ -135,15 +153,16 @@ export function createSendEventForHits({
135153
widgetType: string;
136154
}): SendEventForHits {
137155
const sendEventForHits: SendEventForHits = (...args: any[]) => {
138-
const payload = buildPayload({
156+
const payloads = buildPayloads({
139157
widgetType,
140158
index,
141159
methodName: 'sendEvent',
142160
args,
143161
});
144-
if (payload) {
145-
instantSearchInstance.sendEventToInsights(payload);
146-
}
162+
163+
payloads.forEach((payload) =>
164+
instantSearchInstance.sendEventToInsights(payload)
165+
);
147166
};
148167
return sendEventForHits;
149168
}
@@ -156,13 +175,16 @@ export function createBindEventForHits({
156175
widgetType: string;
157176
}): BindEventForHits {
158177
const bindEventForHits: BindEventForHits = (...args: any[]) => {
159-
const payload = buildPayload({
178+
const payloads = buildPayloads({
160179
widgetType,
161180
index,
162181
methodName: 'bindEvent',
163182
args,
164183
});
165-
return payload ? `data-insights-event=${serializePayload(payload)}` : '';
184+
185+
return payloads.length
186+
? `data-insights-event=${serializePayload(payloads)}`
187+
: '';
166188
};
167189
return bindEventForHits;
168190
}

‎src/lib/utils/serializer.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
export function serializePayload(payload: Record<string, unknown>): string {
1+
export function serializePayload<TPayload>(payload: TPayload): string {
22
return btoa(encodeURIComponent(JSON.stringify(payload)));
33
}
44

5-
export function deserializePayload(payload: string): Record<string, unknown> {
6-
return JSON.parse(decodeURIComponent(atob(payload)));
5+
export function deserializePayload<TPayload>(serialized: string): TPayload {
6+
return JSON.parse(decodeURIComponent(atob(serialized)));
77
}

0 commit comments

Comments
 (0)
Please sign in to comment.