Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/v6-flag-result-follows-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"posthog_flutter": major
---

- **Breaking:** `getFeatureFlagResult()` now follows `PostHogConfig.sendFeatureFlagEvent` when `sendFeatureFlagEvent` is omitted, instead of always capturing `$feature_flag_called`. Pass `sendFeatureFlagEvent: true` to keep capturing the event when the config turns it off
6 changes: 3 additions & 3 deletions api/posthog_flutter.api.json
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,7 @@
"isRequired": false,
"name": "sendFeatureFlagEvent",
"relativePath": "lib/src/posthog_flutter_platform_interface.dart",
"typeName": "bool"
"typeName": "bool?"
}
],
"relativePath": "lib/src/posthog_flutter_platform_interface.dart",
Expand Down Expand Up @@ -2062,7 +2062,7 @@
"isRequired": false,
"name": "sendFeatureFlagEvent",
"relativePath": "lib/src/posthog_flutter_platform_interface.dart",
"typeName": "bool"
"typeName": "bool?"
}
],
"relativePath": "lib/src/posthog_flutter_platform_interface.dart",
Expand Down Expand Up @@ -4845,7 +4845,7 @@
"isRequired": false,
"name": "sendFeatureFlagEvent",
"relativePath": "lib/src/posthog.dart",
"typeName": "bool"
"typeName": "bool?"
}
],
"relativePath": "lib/src/posthog.dart",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1685,7 +1685,7 @@ class PosthogFlutterPlugin :
result.error("PosthogFlutterException", "Missing argument: key", null)
return
}
val sendEvent: Boolean = call.argument("sendEvent") ?: true
val sendEvent: Boolean? = call.argument("sendEvent")
val flagResult = PostHog.getFeatureFlagResult(featureFlagKey, sendEvent)

if (flagResult != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1385,8 +1385,13 @@ extension PosthogFlutterPlugin {
if let args = call.arguments as? [String: Any],
let featureFlagKey = args["key"] as? String
{
let sendEvent = args["sendEvent"] as? Bool ?? true
let flagResult = PostHogSDK.shared.getFeatureFlagResult(featureFlagKey, sendFeatureFlagEvent: sendEvent)
// A missing sendEvent follows config.sendFeatureFlagEvent.
let flagResult: PostHogFeatureFlagResult?
if let sendEvent = args["sendEvent"] as? Bool {
flagResult = PostHogSDK.shared.getFeatureFlagResult(featureFlagKey, sendFeatureFlagEvent: sendEvent)
} else {
flagResult = PostHogSDK.shared.getFeatureFlagResult(featureFlagKey)
}

if let flagResult {
result([
Expand Down
8 changes: 5 additions & 3 deletions posthog_flutter/lib/posthog_flutter_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -466,11 +466,13 @@ class PosthogFlutterWeb extends PosthogFlutterPlatformInterface {
@override
Future<PostHogFeatureFlagResult?> getFeatureFlagResult({
required String key,
bool sendFeatureFlagEvent = true,
bool? sendFeatureFlagEvent,
}) async {
final result = await handleWebMethodCall(
MethodCall('getFeatureFlagResult',
{'key': key, 'sendEvent': sendFeatureFlagEvent}),
MethodCall('getFeatureFlagResult', {
'key': key,
if (sendFeatureFlagEvent != null) 'sendEvent': sendFeatureFlagEvent,
}),
);

// Web SDK returns: { key, enabled, variant, payload }
Expand Down
7 changes: 4 additions & 3 deletions posthog_flutter/lib/src/core/posthog_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -771,10 +771,11 @@ abstract class PostHogCore extends PostHogCoreStateless {
}

/// Gets the result for a specific feature flag, capturing
/// `$feature_flag_called` when [sendEvent] is true.
/// `$feature_flag_called` when [sendEvent] is true, or when it is null and
/// `sendFeatureFlagEvent` is enabled in the config.
PostHogFeatureFlagResult? getFeatureFlagResult(
String key, {
required bool sendEvent,
bool? sendEvent,
}) {
final storedDetails = _getStoredFlagDetails();
final details = storedDetails?.toResponse();
Expand All @@ -783,7 +784,7 @@ abstract class PostHogCore extends PostHogCoreStateless {
true;
final featureFlag = details?.flags[key];
final flagValue = getFeatureFlagValue(featureFlag);
final shouldSendEvent = sendEvent &&
final shouldSendEvent = (sendEvent ?? _sendFeatureFlagEvent) &&
!optedOut &&
!(_flagCallReported[key]?.contains(flagValue) ?? false);

Expand Down
9 changes: 5 additions & 4 deletions posthog_flutter/lib/src/posthog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -788,9 +788,10 @@ class Posthog {
/// This is the canonical method for getting feature flag data.
/// Returns `null` if the flag does not exist or cannot be loaded.
///
/// Set [sendFeatureFlagEvent] to `false` to suppress the
/// `$feature_flag_called` event. This is useful when you only need the
/// payload and do not want to emit the event.
/// [sendFeatureFlagEvent] controls whether this call captures the
/// `$feature_flag_called` event. Defaults to `null`, which follows
/// [PostHogConfig.sendFeatureFlagEvent]. Pass `false` when you only need the
/// payload, or `true` to capture the event even when the config turns it off.
///
/// **Example:**
/// ```dart
Expand All @@ -802,7 +803,7 @@ class Posthog {
/// ```
Future<PostHogFeatureFlagResult?> getFeatureFlagResult(
String key, {
bool sendFeatureFlagEvent = true,
bool? sendFeatureFlagEvent,
}) =>
_posthog.getFeatureFlagResult(
key: key, sendFeatureFlagEvent: sendFeatureFlagEvent);
Expand Down
2 changes: 1 addition & 1 deletion posthog_flutter/lib/src/posthog_flutter_desktop.dart
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ class PosthogFlutterDesktop extends PosthogFlutterPlatformInterface {
@override
Future<PostHogFeatureFlagResult?> getFeatureFlagResult({
required String key,
bool sendFeatureFlagEvent = true,
bool? sendFeatureFlagEvent,
}) =>
_guardWith(
'getFeatureFlagResult',
Expand Down
4 changes: 2 additions & 2 deletions posthog_flutter/lib/src/posthog_flutter_io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ class PosthogFlutterIO extends PosthogFlutterPlatformInterface {
@override
Future<PostHogFeatureFlagResult?> getFeatureFlagResult({
required String key,
bool sendFeatureFlagEvent = true,
bool? sendFeatureFlagEvent,
}) async {
if (!isSupportedPlatform()) {
return null;
Expand All @@ -725,7 +725,7 @@ class PosthogFlutterIO extends PosthogFlutterPlatformInterface {
try {
final result = await _methodChannel.invokeMethod('getFeatureFlagResult', {
'key': key,
'sendEvent': sendFeatureFlagEvent,
if (sendFeatureFlagEvent != null) 'sendEvent': sendFeatureFlagEvent,
});

// Native returns: { key, enabled, variant, payload }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ abstract class PosthogFlutterPlatformInterface extends PlatformInterface {

Future<PostHogFeatureFlagResult?> getFeatureFlagResult({
required String key,
bool sendFeatureFlagEvent = true,
bool? sendFeatureFlagEvent,
}) {
throw UnimplementedError(
'getFeatureFlagResult() has not been implemented.',
Expand Down
4 changes: 2 additions & 2 deletions posthog_flutter/lib/src/posthog_flutter_web_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,11 @@ Future<dynamic> handleWebMethodCall(MethodCall call) async {
return featureFlag?.dartify();
case 'getFeatureFlagResult':
final key = args['key'] as String;
final sendEvent = args['sendEvent'] as bool? ?? true;
final sendEvent = args['sendEvent'] as bool?;

final result = posthog?.getFeatureFlagResult(
stringToJSAny(key),
{'send_event': sendEvent}.jsify(),
{if (sendEvent != null) 'send_event': sendEvent}.jsify(),
);
return result?.dartify();
case 'getAllFeatureFlags':
Expand Down
27 changes: 27 additions & 0 deletions posthog_flutter/test/posthog_flutter_desktop_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1891,6 +1891,33 @@ void main() {
expect(server.eventNames, isNot(contains(r'$feature_flag_called')));
});

test(
r'getFeatureFlagResult follows config.sendFeatureFlagEvent unless overridden',
() async {
final server = await LocalPostHogServer.start();
server.respond = (_) => PostHogResponse.json(_variantFlagResponse());
final flagsLoaded = Completer<void>();
final config = configFor(server)
..sendFeatureFlagEvent = false
..onFeatureFlags = () {
if (!flagsLoaded.isCompleted) flagsLoaded.complete();
};
final platform = await setUpPlatform(config);
await flagsLoaded.future;

expect(
(await platform.getFeatureFlagResult(key: 'variant-flag'))?.variant,
'test-variant');
await platform.capture(eventName: 'sentinel event');
await server.waitForEvent('sentinel event');
expect(server.eventNames, isNot(contains(r'$feature_flag_called')));

await platform.getFeatureFlagResult(
key: 'variant-flag', sendFeatureFlagEvent: true);
final called = await server.waitForEvent(r'$feature_flag_called');
expect(_propertiesOf(called)[r'$feature_flag'], 'variant-flag');
});

test('onFeatureFlags reports the flags cached by the previous launch',
() async {
final server = await LocalPostHogServer.start();
Expand Down
2 changes: 1 addition & 1 deletion posthog_flutter/test/posthog_flutter_io_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void main() {
expect(
await posthogFlutterIO.getFeatureFlagResult(key: 'missing'), isNull);
expect(log.single.method, 'getFeatureFlagResult');
expect(log.single.arguments, {'key': 'missing', 'sendEvent': true});
expect(log.single.arguments, {'key': 'missing'});
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class PosthogFlutterPlatformFake extends PosthogFlutterPlatformInterface {
@override
Future<PostHogFeatureFlagResult?> getFeatureFlagResult({
required String key,
bool sendFeatureFlagEvent = true,
bool? sendFeatureFlagEvent,
}) async {
getFeatureFlagResultCalls
.add({'key': key, 'sendFeatureFlagEvent': sendFeatureFlagEvent});
Expand Down
8 changes: 4 additions & 4 deletions posthog_flutter/test/posthog_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ void main() {
final result = await Posthog().getFeatureFlagResult('non-existent');
expect(result, isNull);
expect(fakePlatformInterface.getFeatureFlagResultCalls, [
{'key': 'non-existent', 'sendFeatureFlagEvent': true}
{'key': 'non-existent', 'sendFeatureFlagEvent': null}
]);
});

Expand All @@ -495,17 +495,17 @@ void main() {
expect(
await Posthog().getFeatureFlagResult('variant-flag'), same(expected));
expect(fakePlatformInterface.getFeatureFlagResultCalls, [
{'key': 'variant-flag', 'sendFeatureFlagEvent': true}
{'key': 'variant-flag', 'sendFeatureFlagEvent': null}
]);
});

test('passes sendFeatureFlagEvent=true by default', () async {
test('leaves sendFeatureFlagEvent to the config by default', () async {
await Posthog().getFeatureFlagResult('test');

expect(
fakePlatformInterface
.getFeatureFlagResultCalls.last['sendFeatureFlagEvent'],
isTrue,
isNull,
);
});

Expand Down
Loading