statsig-io / statsig-feedback

Issue Tracker for Statsig. Leave your feedback on anything we do!
5 stars 0 forks source link

[Bug][DartSDK] ParameterStore.get() fails to retrieve static string array values #51

Open OrcunJoyoLabs opened 4 days ago

OrcunJoyoLabs commented 4 days ago

Description

When attempting to retrieve array values from Parameter Store using the Statsig Dart SDK (v1.2.1), the API consistently returns null or default values, even for the most basic retrieval attempts. This appears to be a fundamental issue with array handling. The parameter "enabled_values" is configured as a static string array in Parameter Store with values like:

[
  "xxxxxxxxxxxxxxxxxxxxxxx1",
  "xxxxxxxxxxxxxxxxxxxxxxx2",
  "xxxxxxxxxxxxxxxxxxxxxxx3",
  "xxxxxxxxxxxxxxxxxxxxxxx4",
  "xxxxxxxxxxxxxxxxxxxxxxx5"
]

Current Behavior

  1. Basic retrieval returns null:

    // Returns null
    dynamic getValues() {
    final storeName = Statsig.getParameterStore("test_store");
    return storeName.get("enabled_values");
    }
  2. Direct casting to List returns null:

    // Returns null
    List<String> getValues() {
    final storeName = Statsig.getParameterStore("test_store");
    return storeName.get("enabled_values") as List<String>;
    }
  3. Casting to List returns null:

    // Returns null
    List<String> getValues() {
    final storeName = Statsig.getParameterStore("test_store");
    return (storeName.get("enabled_values") as List<dynamic>).cast<String>();
    }
  4. Using default value returns only the default:

    // Returns default value only
    List<String> getValues() {
    final storeName = Statsig.getParameterStore("test_store");
    final defaultValue = ['123123'];
    return (storeName.get("enabled_values", defaultValue) as List<dynamic>)
      .cast<String>();
    }
  5. Explicit casting to List using the API, throws

    // Throws 'List<dynamic>' is not a subtype of type 'List<String>' in type cast
    List<String>? getValues() {
    final storeName = Statsig.getParameterStore("test_store");
    return storeName.get<List<String>>("enabled_values");
    }
  6. Current workaround (explicit List typing) (Works):

    // Works but requires unintuitive casting
    List<String> getValues() {
    final storeName = Statsig.getParameterStore("test_store");
    final defaultValue = ['123123'] as List<dynamic>;
    return (storeName.get("enabled_values", defaultValue) as List<dynamic>)
      .cast<String>();
    }

Expected Behavior

The basic get() call should return the configured array value from the Parameter Store.

Environment

Statsig Dart SDK Version: 1.2.1 Dart SDK Version: 3.5.3 Platform: Dart/Flutter Parameter Store Configuration: Static string array value

tore-statsig commented 1 day ago

Thanks for the report, we are taking a look

tore-statsig commented 1 day ago

Interesting, it looks like the only difference between your callsite and our internal test for this is specifying a default value. So we do:

var store =
      Statsig.getParameterStore(name, disableExposureLogging: noExposure);
return store.get("parameter_name", []);

So ill continue to look at this in the case a default is not provided. But if you provide even just an empty array, this should work

OrcunJoyoLabs commented 1 day ago

Thank you for the response @tore-statsig.

Have you had a chance to take a look at the cases I have shared above? If you look at example #4, it returns only the default value when I provide a default, it never returns the existing value from the store.

Also there's the broader problem of typing / casting here. It's super confusing and error prone, as I shared with other examples. store.get("parameter_name", []); completely loses the type, and casting messes things up. Ideally all 6 cases above should return me the correct value.

OrcunJoyoLabs commented 1 day ago

I will actually give you a yet another interesting data point

Try passing a non-empty list as the default value e.g.

var store =
      Statsig.getParameterStore(name, disableExposureLogging: noExposure);
return store.get("parameter_name", ["123"]);

This will always return you the default value you passed.