splitio / redux-client

Redux SDK client for Split Software
https://split.io
Other
5 stars 1 forks source link

getTreatments for different key on sign up #9

Closed LydGol90 closed 6 months ago

LydGol90 commented 4 years ago

Hi there.

I am using split redux in a react native app.

I am attempting to make the getTreatments call again for a different key when a user successfully signs up.

const Splitio = () => {
  const userId = useSelector(getUserId);
  const dispatch = useDispatch();

  const deviceId = DeviceInfo.getUniqueId();

  const splitConfig = {
    core: {
      authorizationKey: XXX
      key: userId || deviceId,
    },
  };

 const onReadyCallback = () => {
    dispatch(
      getTreatments({
        splitNames: ['Developer Settings'],
      }),
    );
  };

  useEffect(() => {
    dispatch(initSplitSdk({ config: splitConfig, onReady: onReadyCallback }));
  }, []);

  useEffect(() => {
    dispatch(
      getTreatments({
        splitNames: ['Developer Settings'],
        key: userId || deviceId,
      }),
    );
  }, [userId]);
};

When the userId changes I see the ADD TREATMENTS action and my split redux slice now looks like this:

treatments: {
      Developer_Settings: {
        '3C2115DF-0E46-4DF7-9AF9-B7CA7D95543D': {
          treatment: 'off',
          config: null
        },
        '25febe55-4d44-523c-9df6-a354b03ed5ca': {
          treatment: 'off',
          config: null
        }
      },
}

However it is returning the wrong treatment for this user, it should be on.

If I then close the app and open again (allowing the sdk to initialise again) I see the correct treatment.

I have identified the reason why it is unable to get the correct treatment. If I inspect the response from the initial call made to the split server I can see all the splits and the conditions as expected. However my condition for this split 'Developer Settings' is based on the user being in a particular segment (created manually on Split interface). I can see in the response from the server that the condition is that anyone in segment 'Engineering' should see the "on" treatment, however there are no details in the response about which users are in the 'Engineering' segment. Therefore there is no way to evaluate this treatment correctly locally, and so I need some way to force the SDK to fetch all the data from the server again. Is there some other way to do this without initialising the SDK again?

If I do re-initialise the SDK it all works but it feels wrong initialising again?

const Splitio = () => {
  const userId = useSelector(getUserId);
  const dispatch = useDispatch();

  const firstName = useSelector(getFirstName) || '';
  const deviceId = DeviceInfo.getUniqueId();

  const splitConfig = {
    core: {
      authorizationKey: XXX,
      key: userId || deviceId,
    },
  };

  const onReadyCallback = () => {
    dispatch(
      getTreatments({
        splitNames: ['Developer Settings'],
      }),
    );
  };

  useEffect(() => {
    dispatch(initSplitSdk({ config: splitConfig, onReady: onReadyCallback }));
  }, [userId]);

};

Hope that makes sense!

Many thanks for any help.

NicoZelaya commented 4 years ago

Hi @LydGol90 !

Thank you very much for reporting the issue, our apologies for not providing a response sooner.

It does make sense! I went ahead and scheduled it for next week, we'll probably release a patch version and let you know once it's out as stable. Thanks again for the feedback!

Kind regards, Nico.

LydGol90 commented 4 years ago

Hi @NicoZelaya, many thanks for your response.

I went back to using the JS sdk and found that with theirs the sdk onReady callback is automatically called again if the key changes. Would be nice if this one could work in the same way as then I don't even have to listen for userId changes myself it just does it!

EmilianoSanchez commented 6 months ago

Hi @LydGol90 ,

It has been a long time since you opened this issue. It was resolved in version 1.1.0 of the Redux SDK. The issue was caused by not waiting for the fetch of segments when using the getTreatments action creator with a different user key than the default. So, I am closing it.

Additionally, we have just released version 1.13.0 of the SDK, which includes a new helper function called getStatus to get the status of the SDK client (e.g., if it is ready, ready from cache, etc.) for a given key. We also introduced two new selectors that can be used as alternatives to the existing selectTreatmentValue and selectTreatmentWithConfig selectors. These new selectors retrieve the treatment together with the client status for the given key.

Example:

import { getStatus, selectTreatmentAndStatus, selectTreatmentWithConfigAndStatus } from '@splitsoftware/splitio-redux';

const { isReady, isReadyFromCache, hasTimedout, isDestroyed } = getStatus(optionalKey);

const { treatment, isReady, isReadyFromCache, hasTimedout, isDestroyed } = selectTreatmentAndStatus(splitState, featureFlagName, optionalKey, optionalDefaultTreatment);

const { treatment, isReady, isReadyFromCache, hasTimedout, isDestroyed } = selectTreatmentWithConfigAndStatus(splitState, featureFlagName, optionalKey, optionalDefaultTreatment);

This can help with conditional rendering based on the SDK status:

const MyComponent = ({ userId }) => {
  const { treatment, isReady } = useSelector((state) => {
    return selectTreatmentAndStatus(state.splitio, FEATURE_FLAG_NAME, userId);
  })

  return isReady ?
    treatment === 'on' ?
      <ComponentOn /> :
      <ComponentOff /> :
    <Loading />
}

More info about this features will be soon available in our public docs.