KNOWLEDGE BASE

Useful treasure trove of knowledge

Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:54 PM
cc: MA (Statsig)
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:54 PM
no problem. The reason we don’t have an easy way to do this is because this is very easily misused and will lead to the wrong result, but we do know there are legit use cases, and that’s one of the reason why we have the API for you to log your own user’s group right now. I can see us implementing something that will help you find the right/balanced randomization based on some criteria at some point, or maybe a way to allow you to use overrides and include them in the results too. It’s not on our short term roadmap yet, but I think longer term we will likely support this better
tore (statsig)
Friday, November 11, 2022 at 7:53 PM
If you used the loading indicator in that specific hook call, you could block loading that single component
Eric Zimanyi
Friday, November 11, 2022 at 7:48 PM
longer-term are there any plans to improve support for this use case in the product?
Sahil Ahuja
Friday, November 11, 2022 at 7:48 PM
Will have to re-evaluate later on if we want to add an experiment on homepage -- I'm not sure if it's possible to block loading of a specific part of homepage using waitForInitialization (anyways not a priority to figure out right now)
Eric Zimanyi
Friday, November 11, 2022 at 7:48 PM
ok, thanks! yeah, I think that for the short-term one of these will be a reasonable workaround
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:47 PM
then you won’t worry about new clients falling into the experiment
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:47 PM
what you should do is create a gate that passes if the client id is not any of the 20, and then override that gate to control
tore (statsig)
Friday, November 11, 2022 at 7:47 PM
Im still trying to reproduce the issue you described
Sahil Ahuja
Friday, November 11, 2022 at 7:46 PM
At this point I'm comfortable with that because we don't have gates that affect the homepage
tore (statsig)
Friday, November 11, 2022 at 7:46 PM
Everybody prefers not to wait, but I would keep in mind the side effects of not waiting. It will render you app immediately, but the values wont be up to date with what youve defined in Statsig. Once the initialization does complete, it will rerender with the new values, which can cause a flicker if the experience changes
Eric Zimanyi
Friday, November 11, 2022 at 7:46 PM
The reason is that we are signing up new clients, so having an exclusion list in the experiment would not be super maintainable
Eric Zimanyi
Friday, November 11, 2022 at 7:45 PM
For the first solution (randomizing) would it also be reasonable to set up a gate before the experiment to filter to the client ids we're interested in?
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:44 PM
These 2 options give you the same result, one is a little more tedious and needs some luck to get the right randomization, one is more coding but give you precise control of who falls into which group, so up to you which one to go with
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:43 PM
If you want full control of who is in which group without keep resetting the experiment, then the only way is using the http api to manually log their exposure, and make sure in your code, you do ```let controlIDs = [...]; // hard code your client ids in these let testIDs = [...]; if (controlIDs.contains(clientID)) { // call the http api to expose the client to control group, then show control group experience } else if (testIDs.contains(clientID)) { // call the http api to expose the client to control group, then show test group experience } else { // do whatever is right for the rest }```
Sahil Ahuja
Friday, November 11, 2022 at 7:42 PM
(It works well when I set waitForInitialization to true, but unfortunately that breaks the loading state for my app so prefer not to wait)
Sahil Ahuja
Friday, November 11, 2022 at 7:41 PM
The https://www.npmjs.com/package/statsig-react-native/v/4.7.2-beta.0|4.7.2-beta.0 version that you very helpfully got working for me yesterday :slightly_smiling_face:
tore (statsig)
Friday, November 11, 2022 at 7:41 PM
Which version of the sdk are you using?
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:40 PM
Then for the 20, do what I suggested earlier to reset the randomization a few times until they are split evenly
Sahil Ahuja
Friday, November 11, 2022 at 7:39 PM
I have an App.tsx that's the root of my React Native Project, within that I'm putting my own StatsigProvider StatsigProvider.tsx: ```import type { FC, ReactNode } from 'react'; import React from 'react'; import env from 'react-native-config'; import DeviceInfo from 'react-native-device-info'; import { StatsigProvider as StatsigDefaultProvider } from 'statsig-react-native'; import { useAuthContext } from '../contexts/AuthContext'; const StatsigProvider: FC<{ children: ReactNode }> = ({ children }) => { const { userNid, currentUser } = useAuthContext(); return ( <StatsigDefaultProvider sdkKey={env.STATSIG_API_KEY} user={{ userID: userNid ?? undefined, appVersion: DeviceInfo.getBuildNumber().toString(), custom: { isInternal: currentUser?.isInternal ?? undefined, username: currentUser?.username ?? undefined, }, }} waitForInitialization={false} > {children} </StatsigDefaultProvider> ); }; export default StatsigProvider;``` App.tsx: ```const App: FC = () => { return ( <AuthProvider> <StatsigProvider> <MainNavigator /> </StatsigProvider> </AuthProvider> ); };``` MainNavigator.tsx: ``` const MainNavigator: FC = () => { const {value, isLoading } = useGate(StatsigGate.TEST); console.log(value); return ( <Stack.Navigator screenOptions={ScreenOptions}> <Stack.Screen name={NavigatorName.TAB} component={TabNavigator} /> </Stack.Navigator> ); }; export default MainNavigator;```
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:39 PM
Yeah then you can do what i said just now - override everyone else into control so they aren’t in the experiment (you can also write code to check if they are in the 20, and if not, don’t expose to the experiment).
Eric Zimanyi
Friday, November 11, 2022 at 7:38 PM
(And definitely just interested in the best way of doing this, if my approach is not best!)
Eric Zimanyi
Friday, November 11, 2022 at 7:38 PM
Sorry if that was not clear above!
Eric Zimanyi
Friday, November 11, 2022 at 7:38 PM
No, we only want to run the experiment and collect data on these. To clarify: • We have X (>>20) clients • We have selected 20 we want to use for the experiment, 10 in control and 10 in experiment • We'd like to manually set up those 20 in the experiment
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:37 PM
If you don’t want them to be in the result, you can simply override them into the control group, so that they all get the control experience and not included in the result. Let me know if there is a reason you still want to randomize their groups
Sahil Ahuja
Friday, November 11, 2022 at 7:36 PM
Will share here:
Sahil Ahuja
Friday, November 11, 2022 at 7:36 PM
I've tried both and same issue
tore (statsig)
Friday, November 11, 2022 at 7:36 PM
Are you using the useGate hook or trying to call checkGate directly?
tore (statsig)
Friday, November 11, 2022 at 7:34 PM
Can you share some of your code?
Sahil Ahuja
Friday, November 11, 2022 at 7:33 PM
Shug Ghosh
Friday, November 11, 2022 at 7:32 PM
I use `initializeCalled` - `Statsig.initializeCalled()`. IIRC I don't think this is in the React SDK documentation, but it's available in the call
Sahil Ahuja
Friday, November 11, 2022 at 7:31 PM
No :confused: it's directly within the component tree wrapped by the provider
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:29 PM
That error should only be thrown if you are checking the value of a gate before the initialization has even started. Are you using the useGate hook outside of the component wrapped by the provider?
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:27 PM
the `useGate` hook has a `isLoading` state that you can use to see if it’s initialized https://docs.statsig.com/client/reactSDK#usegate
Sahil Ahuja
Friday, November 11, 2022 at 7:27 PM
I'm getting a StatsigUninitializedError if I don't wait for initialization
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:29 PM
That error should only be thrown if you are checking the value of a gate before the initialization has even started. Are you using the useGate hook outside of the component wrapped by the provider?
Sahil Ahuja
Friday, November 11, 2022 at 7:31 PM
No :confused: it's directly within the component tree wrapped by the provider
Sahil Ahuja
Friday, November 11, 2022 at 7:33 PM
tore (statsig)
Friday, November 11, 2022 at 7:34 PM
Can you share some of your code?
tore (statsig)
Friday, November 11, 2022 at 7:36 PM
Are you using the useGate hook or trying to call checkGate directly?
Sahil Ahuja
Friday, November 11, 2022 at 7:36 PM
I've tried both and same issue
Sahil Ahuja
Friday, November 11, 2022 at 7:36 PM
Will share here:
Sahil Ahuja
Friday, November 11, 2022 at 7:39 PM
I have an App.tsx that's the root of my React Native Project, within that I'm putting my own StatsigProvider StatsigProvider.tsx: ```import type { FC, ReactNode } from 'react'; import React from 'react'; import env from 'react-native-config'; import DeviceInfo from 'react-native-device-info'; import { StatsigProvider as StatsigDefaultProvider } from 'statsig-react-native'; import { useAuthContext } from '../contexts/AuthContext'; const StatsigProvider: FC<{ children: ReactNode }> = ({ children }) => { const { userNid, currentUser } = useAuthContext(); return ( <StatsigDefaultProvider sdkKey={env.STATSIG_API_KEY} user={{ userID: userNid ?? undefined, appVersion: DeviceInfo.getBuildNumber().toString(), custom: { isInternal: currentUser?.isInternal ?? undefined, username: currentUser?.username ?? undefined, }, }} waitForInitialization={false} > {children} </StatsigDefaultProvider> ); }; export default StatsigProvider;``` App.tsx: ```const App: FC = () => { return ( <AuthProvider> <StatsigProvider> <MainNavigator /> </StatsigProvider> </AuthProvider> ); };``` MainNavigator.tsx: ``` const MainNavigator: FC = () => { const {value, isLoading } = useGate(StatsigGate.TEST); console.log(value); return ( <Stack.Navigator screenOptions={ScreenOptions}> <Stack.Screen name={NavigatorName.TAB} component={TabNavigator} /> </Stack.Navigator> ); }; export default MainNavigator;```
tore (statsig)
Friday, November 11, 2022 at 7:41 PM
Which version of the sdk are you using?
Sahil Ahuja
Friday, November 11, 2022 at 7:41 PM
The https://www.npmjs.com/package/statsig-react-native/v/4.7.2-beta.0|4.7.2-beta.0 version that you very helpfully got working for me yesterday :slightly_smiling_face:
Sahil Ahuja
Friday, November 11, 2022 at 7:42 PM
(It works well when I set waitForInitialization to true, but unfortunately that breaks the loading state for my app so prefer not to wait)
tore (statsig)
Friday, November 11, 2022 at 7:46 PM
Everybody prefers not to wait, but I would keep in mind the side effects of not waiting. It will render you app immediately, but the values wont be up to date with what youve defined in Statsig. Once the initialization does complete, it will rerender with the new values, which can cause a flicker if the experience changes
Sahil Ahuja
Friday, November 11, 2022 at 7:46 PM
At this point I'm comfortable with that because we don't have gates that affect the homepage
tore (statsig)
Friday, November 11, 2022 at 7:47 PM
Im still trying to reproduce the issue you described
Sahil Ahuja
Friday, November 11, 2022 at 7:48 PM
Will have to re-evaluate later on if we want to add an experiment on homepage -- I'm not sure if it's possible to block loading of a specific part of homepage using waitForInitialization (anyways not a priority to figure out right now)
tore (statsig)
Friday, November 11, 2022 at 7:53 PM
If you used the loading indicator in that specific hook call, you could block loading that single component
tore (statsig)
Friday, November 11, 2022 at 8:08 PM
hmm Im still unable to reproduce the issue, with `waitForInitialization` false, I just get `isLoading: true, value: false` for `useGate` calls in my component hierarchy
tore (statsig)
Friday, November 11, 2022 at 8:09 PM
(side note, we did publish `4.8.0` as a production version with the other fix we discussed, so you dont have to use the beta version any more
Sahil Ahuja
Friday, November 11, 2022 at 8:09 PM
Hmm that's weird -- ok will try upgrading to that version and circle back
tore (statsig)
Friday, November 11, 2022 at 8:11 PM
To simplify things a bit and try to narrow in on the issue, maybe just simplify the user object you are setting on the provider? Like just hard code it to {userID: “test”}
Sahil Ahuja
Friday, November 11, 2022 at 8:13 PM
Nope that didn't do it
Sahil Ahuja
Friday, November 11, 2022 at 8:16 PM
Ok I found it -- seems like the issue is with how I was declaring the StatsigProvider in a separate file
Sahil Ahuja
Friday, November 11, 2022 at 8:16 PM
Not sure why that would affect things :man-shrugging:
Sahil Ahuja
Friday, November 11, 2022 at 8:16 PM
I moved it into App.tsx and works fine
tore (statsig)
Friday, November 11, 2022 at 8:19 PM
Huh, strange
tore (statsig)
Friday, November 11, 2022 at 8:19 PM
I’m not sure I have an explanation for that, but Im glad its working for you!
Sahil Ahuja
Friday, November 11, 2022 at 8:26 PM
Would any part of the internal implementation of the Provider cause this to happen? It's a bit annoying now because I need to access another context from the same file to get the user info :sweat_smile:
tore (statsig)
Friday, November 11, 2022 at 8:29 PM
Not that I can think of. Could it be something weird with naming it the same thing as the exported StatsigProvider from the sdk?
Sahil Ahuja
Friday, November 11, 2022 at 8:56 PM
So the issue is with calling useAuthContext() from within the Statsig provider i'm creating -- the AuthProvider has all the info on the current user, so without it I can properly initialize the userNid / etc. If I remove the useAuthContext() and instead try grabbing the id directly from async storage, it also gives the same error saying call and wait for initialization to finish. If I remove all this code and just send in 'test' for nid it works fine ```import type { FC, ReactNode } from 'react'; import React, { useEffect, useState, memo } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; import env from 'react-native-config'; import DeviceInfo from 'react-native-device-info'; import { StatsigProvider } from 'statsig-react-native'; const MyStatsigProvider: FC<{ children: ReactNode; }> = ({ children }) => { // const { userNid, currentUser, initialize } = useAuthContext(); const [userNid, setUserNid] = useState<number | null>(null); useEffect(() => { void (async () => { const _userNid = (await AsyncStorage.getItem('nid')) ?? null; setUserNid(_userNid != null ? parseInt(_userNid) : null); })(); }, []); return ( <StatsigProvider sdkKey={env.STATSIG_API_KEY} user={{ userID: userNid ?? undefined, appVersion: DeviceInfo.getBuildNumber().toString(), custom: { // isInternal: currentUser?.isInternal ?? undefined, // username: currentUser?.username ?? undefined, }, }} waitForInitialization={false} > {children} </StatsigProvider> ); }; export default MyStatsigProvider;```
Sahil Ahuja
Friday, November 11, 2022 at 8:57 PM
Seems the issue has to do with setting any state here
Sahil Ahuja
Friday, November 11, 2022 at 8:57 PM
Without doing that though not sure what you recommend for grabbing the userId
tore (statsig)
Friday, November 11, 2022 at 9:26 PM
Hmm interesting. So when the user object changes, we do have to re-trigger the network request to update the values. Are you able to only render the provider once you’ve fetched those values?
Sahil Ahuja
Friday, November 11, 2022 at 9:31 PM
Ok yes that works now :slightly_smiling_face: Thanks again for helping me get to the bottom of this. If I return early when userNid is null then it works
tore (statsig)
Friday, November 11, 2022 at 9:36 PM
Hmm okay, the SDK still shouldn’t throw in that case so we will look into that, but I think this is a better integration anyway
Sahil Ahuja
Friday, November 11, 2022 at 7:25 PM
On React / React native, is there a way to check whether Statsig has been initialized before checking a gate, so I don't need to set waitForInitialization to true? I don't want to block the loading of my App
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:27 PM
the `useGate` hook has a `isLoading` state that you can use to see if it’s initialized https://docs.statsig.com/client/reactSDK#usegate
Shug Ghosh
Friday, November 11, 2022 at 7:32 PM
I use `initializeCalled` - `Statsig.initializeCalled()`. IIRC I don't think this is in the React SDK documentation, but it's available in the call
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:25 PM
if you don’t want their result, why still put them in the experiment?
Jiakan Wang (Statsig)
Friday, November 11, 2022 at 7:25 PM
do you want to run the experiment on the rest of the clients?
Eric Zimanyi
Friday, November 11, 2022 at 7:11 PM
I assume that if I start the experiment and reallocate it will allocate *all* the client ids, and there's not a good way to filter down to just these 20?
Eric Zimanyi
Friday, November 11, 2022 at 7:11 PM
One additional point that I probably didn't make clear above is that we have many more than 20 clients, but we only want these 20 to be in the experiment results (as they are picked specifically for being representative for this experiment).

We use cookies to ensure you get the best experience on our website.

Privacy Policy