Skip to content

Commit de199e8

Browse files
authored
Merge pull request #7814 from QwikDev/v2-context-falsy-value
fix: handle falsy value as context value
2 parents 9052a8d + 08c3a0c commit de199e8

File tree

6 files changed

+65
-19
lines changed

6 files changed

+65
-19
lines changed

.changeset/silly-symbols-sleep.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
fix: handle falsy value as context value

packages/qwik/src/core/client/dom-container.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ import {
7373
vnode_setProp,
7474
type VNodeJournal,
7575
} from './vnode';
76-
import { mapArray_get, mapArray_set } from './util-mapArray';
76+
import { mapArray_get, mapArray_has, mapArray_set } from './util-mapArray';
7777

7878
/** @public */
7979
export function getDomContainer(element: Element | VNode): IClientContainer {
@@ -220,20 +220,17 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
220220

221221
setContext<T>(host: HostElement, context: ContextId<T>, value: T): void {
222222
let ctx = this.getHostProp<Array<string | unknown>>(host, QCtxAttr);
223-
if (!ctx) {
223+
if (ctx == null) {
224224
this.setHostProp(host, QCtxAttr, (ctx = []));
225225
}
226-
mapArray_set(ctx, context.id, value, 0);
226+
mapArray_set(ctx, context.id, value, 0, true);
227227
}
228228

229229
resolveContext<T>(host: HostElement, contextId: ContextId<T>): T | undefined {
230230
while (host) {
231231
const ctx = this.getHostProp<Array<string | unknown>>(host, QCtxAttr);
232-
if (ctx) {
233-
const value = mapArray_get(ctx, contextId.id, 0) as T;
234-
if (value) {
235-
return value as T;
236-
}
232+
if (ctx != null && mapArray_has(ctx, contextId.id, 0)) {
233+
return mapArray_get(ctx, contextId.id, 0) as T;
237234
}
238235
host = this.getParentHost(host)!;
239236
}

packages/qwik/src/core/client/util-mapArray.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,17 @@ export const mapArray_set = <T>(
2525
array: (T | null)[],
2626
key: string,
2727
value: T | null,
28-
start: number
28+
start: number,
29+
allowNullValue: boolean = false
2930
) => {
3031
const indx = mapApp_findIndx(array, key, start);
3132
if (indx >= 0) {
32-
if (value == null) {
33+
if (value == null && !allowNullValue) {
3334
array.splice(indx, 2);
3435
} else {
3536
array[indx + 1] = value;
3637
}
37-
} else if (value != null) {
38+
} else if (value != null || allowNullValue) {
3839
array.splice(indx ^ -1, 0, key as any, value);
3940
}
4041
};

packages/qwik/src/core/qwik.core.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ export const _mapApp_findIndx: <T>(array: (T | null)[], key: string, start: numb
525525
export const _mapArray_get: <T>(array: (T | null)[], key: string, start: number) => T | null;
526526

527527
// @internal (undocumented)
528-
export const _mapArray_set: <T>(array: (T | null)[], key: string, value: T | null, start: number) => void;
528+
export const _mapArray_set: <T>(array: (T | null)[], key: string, value: T | null, start: number, allowNullValue?: boolean) => void;
529529

530530
// @public @deprecated (undocumented)
531531
export type NativeAnimationEvent = AnimationEvent;

packages/qwik/src/core/tests/use-context.spec.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,51 @@ describe.each([
196196
}
197197
});
198198

199+
it('should find context with falsy value', async () => {
200+
const ctxIf = createContextId<any>('if');
201+
const ctxIf2 = createContextId<any>('if2');
202+
const ctxIf3 = createContextId<any>('if3');
203+
204+
const Child = component$(() => {
205+
const value = useContext(ctxIf);
206+
const value2 = useContext(ctxIf2);
207+
const value3 = useContext(ctxIf3);
208+
return (
209+
<>
210+
{value}
211+
{value2}
212+
{value3}
213+
</>
214+
);
215+
});
216+
217+
const Cmp = component$(() => {
218+
useContextProvider(ctxIf, '');
219+
useContextProvider(ctxIf2, false);
220+
useContextProvider(ctxIf3, null);
221+
return (
222+
<div>
223+
<Child />
224+
</div>
225+
);
226+
});
227+
228+
const { vNode } = await render(<Cmp />, { debug });
229+
expect(vNode).toMatchVDOM(
230+
<Component ssr-required>
231+
<div>
232+
<Component ssr-required>
233+
<Fragment ssr-required>
234+
{''}
235+
{''}
236+
{''}
237+
</Fragment>
238+
</Component>
239+
</div>
240+
</Component>
241+
);
242+
});
243+
199244
describe('regression', () => {
200245
it('#4038', async () => {
201246
interface IMyComponent {

packages/qwik/src/server/ssr-container.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
escapeHTML,
4545
isClassAttr,
4646
mapArray_get,
47+
mapArray_has,
4748
mapArray_set,
4849
maybeThen,
4950
qError,
@@ -263,10 +264,10 @@ class SSRContainer extends _SharedContainer implements ISSRContainer {
263264
setContext<T>(host: HostElement, context: ContextId<T>, value: T): void {
264265
const ssrNode: ISsrNode = host as any;
265266
let ctx: Array<string | unknown> = ssrNode.getProp(QCtxAttr);
266-
if (!ctx) {
267+
if (ctx == null) {
267268
ssrNode.setProp(QCtxAttr, (ctx = []));
268269
}
269-
mapArray_set(ctx, context.id, value, 0);
270+
mapArray_set(ctx, context.id, value, 0, true);
270271
// Store the node which will store the context
271272
this.addRoot(ssrNode);
272273
}
@@ -275,11 +276,8 @@ class SSRContainer extends _SharedContainer implements ISSRContainer {
275276
let ssrNode: ISsrNode | null = host as any;
276277
while (ssrNode) {
277278
const ctx: Array<string | unknown> = ssrNode.getProp(QCtxAttr);
278-
if (ctx) {
279-
const value = mapArray_get(ctx, contextId.id, 0) as T;
280-
if (value) {
281-
return value;
282-
}
279+
if (ctx != null && mapArray_has(ctx, contextId.id, 0)) {
280+
return mapArray_get(ctx, contextId.id, 0) as T;
283281
}
284282
ssrNode = ssrNode.parentSsrNode;
285283
}

0 commit comments

Comments
 (0)