diff --git a/Countly.d.ts b/Countly.d.ts index 8de656e9..ad039875 100644 --- a/Countly.d.ts +++ b/Countly.d.ts @@ -1,5 +1,7 @@ +type SegmentationValue = number | string | boolean | SegmentationValue[] | { [key: string]: SegmentationValue }; + interface Segmentation { - [key: string]: number | string | boolean; + [key: string]: SegmentationValue; } interface CountlyEventOptions { diff --git a/Validators.js b/Validators.js index 9f09e424..ad73fa10 100644 --- a/Validators.js +++ b/Validators.js @@ -134,28 +134,23 @@ function areEventParametersValid(functionName, eventName, segmentation, eventCou return false; } - // validate segmentation values if (segmentation) { for (const key in segmentation) { const value = segmentation[key]; - const valueType = typeof value; - if (value && valueType !== "string" && valueType !== "number" && valueType !== "boolean") { - L.w(`${functionName}, segmentation value: [${value}] for the key: [${key}] must be a number, string or boolean!`); + if (!value) { + L.w(`${functionName}, provided value for the key: [${key}] is null!`); return false; } } } - if (eventCount && (typeof eventCount !== "number" || eventCount < 0)) { L.w(`${functionName}, provided eventCount: [${eventCount}]. It must be a positive number!`); return false; } - if (eventSum && typeof eventSum !== "number") { L.w(`${functionName}, provided eventSum: [${eventSum}]. It must be a number!`); return false; } - return true; } diff --git a/android/src/main/java/ly/count/android/sdk/react/CountlyReactNative.java b/android/src/main/java/ly/count/android/sdk/react/CountlyReactNative.java index 5ccfda9a..5e738b44 100644 --- a/android/src/main/java/ly/count/android/sdk/react/CountlyReactNative.java +++ b/android/src/main/java/ly/count/android/sdk/react/CountlyReactNative.java @@ -1680,6 +1680,30 @@ public Map convertToEventMap(ReadableArray segments) { segmentation.put(key, doubleValue); } break; + case Array: + ReadableArray arrayValue = segments.getArray(i + 1); + List arrayList = new ArrayList<>(); + for (int j = 0; j < arrayValue.size(); j++) { + ReadableType elementType = arrayValue.getType(j); + switch (elementType) { + case String: + arrayList.add(arrayValue.getString(j)); + break; + case Boolean: + arrayList.add(arrayValue.getBoolean(j)); + break; + case Number: + double elemDouble = arrayValue.getDouble(j); + int elemInt = (int) elemDouble; + arrayList.add(elemDouble == elemInt ? elemInt : elemDouble); + break; + default: + // Skip non-primitive types + break; + } + } + segmentation.put(key, arrayList); + break; default: // Skip other types break; diff --git a/example/CountlyRNExample/Events.tsx b/example/CountlyRNExample/Events.tsx index e6276732..fb2e2650 100644 --- a/example/CountlyRNExample/Events.tsx +++ b/example/CountlyRNExample/Events.tsx @@ -13,9 +13,28 @@ const eventWithSum = () => { Countly.events.recordEvent("Event With Sum", undefined, 1, 0.99); }; const eventWithSegment = () => { - // example for event with segment - Countly.events.recordEvent("Event With Segment", { Country: "Paris", Age: 28 }, 1, undefined); - Countly.events.recordEvent("Event With Segment", { Country: "France", Age: 38 }, 1, undefined); + const segment: Segmentation = { + stringList: ['value1', 'value2', 'value3'], + intList: [1, 2, 3], + doubleList: [1.1, 2.2, 3.3], + boolList: [true, false, true], + mixedList: ['value1', 2, 3.3, true], + mapList: [ // currently this is not supported + { key1: 'value1', key2: 2 }, + { key1: 'value2', key2: 3 }, + { key1: 'value3', key2: 4 } + ], + nestedList: [ // currently this is not supported + ['value1', 'value2'], + ['value3', 'value4'], + ['value5', 'value6'] + ], + normalString: 'normalString', + normalInt: 1, + normalDouble: 1.1, + normalBool: true + }; + Countly.events.recordEvent("Event With Segment With Mixed Types", segment, 1, undefined); }; const eventWithSumAndSegment = () => { // example for event with segment and sum