Skip to content

Commit 324bbce

Browse files
authored
feat: allow bootstraped flags to be used even if client fails to init (#202)
**Requirements** - [ ] I have added test coverage for new or changed functionality - [ ] I have followed the repository's [pull request submission guidelines](../blob/main/CONTRIBUTING.md#submitting-pull-requests) - [ ] I have validated my changes against all supported platform versions **Related issues** #152 **Describe the solution you've provided** This solution just maintains any flags that were bootstrapped, in the event of an error while initializing the client (as is the case when I don't use any `clientSideId` locally) **Describe alternatives you've considered** The alternative would be a proper offline-mode implementation that was requested already in #152 **Additional context** currently using this as a patch (to be used with [patch-package](https://www.npmjs.com/package/patch-package), add `patches/launchdarkly-react-client-sdk+3.0.6.patch`): ``` diff --git a/node_modules/launchdarkly-react-client-sdk/lib/provider.js b/node_modules/launchdarkly-react-client-sdk/lib/provider.js index c4f17b2..e901bb6 100644 --- a/node_modules/launchdarkly-react-client-sdk/lib/provider.js +++ b/node_modules/launchdarkly-react-client-sdk/lib/provider.js @@ -73,16 +73,18 @@ class LDProvider extends react_1.Component { const { clientSideID, flags, options } = this.props; let ldClient = yield this.props.ldClient; const reactOptions = this.getReactOptions(); - let unproxiedFlags; + let unproxiedFlags = this.state.unproxiedFlags; let error; if (ldClient) { unproxiedFlags = (0, utils_1.fetchFlags)(ldClient, flags); } else { const initialisedOutput = yield (0, initLDClient_1.default)(clientSideID, (0, utils_1.getContextOrUser)(this.props), options, flags); - unproxiedFlags = initialisedOutput.flags; - ldClient = initialisedOutput.ldClient; error = initialisedOutput.error; + if(!error) { + unproxiedFlags = initialisedOutput.flags; + } + ldClient = initialisedOutput.ldClient; } this.setState(Object.assign(Object.assign({ unproxiedFlags }, (0, getFlagsProxy_1.default)(ldClient, unproxiedFlags, reactOptions, flags)), { ldClient, error })); this.subscribeToChanges(ldClient); ```
2 parents c747332 + 5bb4ddb commit 324bbce

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/provider.test.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,40 @@ describe('LDProvider', () => {
169169
expect(initialState.flags).toEqual({});
170170
});
171171

172+
test('ld client keeps bootstrapped flags, even when it failed to initialize', async () => {
173+
const context: LDContext = { key: 'yus', kind: 'user', name: 'yus ng' };
174+
const options: LDOptions = {
175+
bootstrap: {
176+
'test-flag': true
177+
}
178+
};
179+
const props: ProviderConfig = { clientSideID, context, options };
180+
181+
mockInitLDClient.mockImplementation(() => ({
182+
error: true,
183+
flags: {},
184+
ldClient: mockLDClient,
185+
}));
186+
187+
const LaunchDarklyApp = (
188+
<LDProvider {...props}>
189+
<App />
190+
</LDProvider>
191+
);
192+
const instance = create(LaunchDarklyApp).root.findByType(LDProvider).instance as EnhancedComponent
193+
instance.setState = jest.fn();
194+
await instance?.componentDidMount()
195+
196+
expect(mockInitLDClient).toHaveBeenCalledWith(clientSideID, context, options, undefined);
197+
expect(instance.setState).toHaveBeenCalledWith({
198+
error: true,
199+
flags: { testFlag: true},
200+
unproxiedFlags: { 'test-flag': true,},
201+
flagKeyMap: { testFlag: 'test-flag'},
202+
ldClient: mockLDClient,
203+
});
204+
});
205+
172206
test('ld client is bootstrapped correctly and transforms keys to camel case', () => {
173207
const context: LDContext = { key: 'yus', kind: 'user', name: 'yus ng' };
174208
const options: LDOptions = {

src/provider.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,17 @@ class LDProvider extends Component<PropsWithChildren<ProviderConfig>, LDHocState
7777
const { clientSideID, flags, options } = this.props;
7878
let ldClient = await this.props.ldClient;
7979
const reactOptions = this.getReactOptions();
80-
let unproxiedFlags;
80+
let unproxiedFlags = this.state.unproxiedFlags;
8181
let error: Error | undefined;
8282
if (ldClient) {
8383
unproxiedFlags = fetchFlags(ldClient, flags);
8484
} else {
8585
const initialisedOutput = await initLDClient(clientSideID, getContextOrUser(this.props), options, flags);
86-
unproxiedFlags = initialisedOutput.flags;
87-
ldClient = initialisedOutput.ldClient;
8886
error = initialisedOutput.error;
87+
if (!error) {
88+
unproxiedFlags = initialisedOutput.flags;
89+
}
90+
ldClient = initialisedOutput.ldClient;
8991
}
9092
this.setState({ unproxiedFlags, ...getFlagsProxy(ldClient, unproxiedFlags, reactOptions, flags), ldClient, error });
9193
this.subscribeToChanges(ldClient);

0 commit comments

Comments
 (0)