Skip to content

Commit 3fa08d5

Browse files
authored
fix: show :then block for null value (#14440)
fixes #14439 This bug was introduced in #13642 because setting the input to null means the equality check ("is the input different") fails if you set the value to null Also fixes #14441 - this bug was present for a long time, and the reason is the same as for the other bug: The equality check always returns "yes this is the same" if the value is undefined initially. The fix is similar; we need to initialize the input to something that can never be equal to whatever value is passed
1 parent 9e9fb24 commit 3fa08d5

File tree

4 files changed

+41
-12
lines changed

4 files changed

+41
-12
lines changed

.changeset/breezy-insects-live.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: show `:then` block for `null/undefined` value

packages/svelte/src/internal/client/dom/blocks/await.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from '../../runtime.js';
1515
import { hydrate_next, hydrate_node, hydrating } from '../hydration.js';
1616
import { queue_micro_task } from '../task.js';
17+
import { UNINITIALIZED } from '../../../../constants.js';
1718

1819
const PENDING = 0;
1920
const THEN = 1;
@@ -40,8 +41,8 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) {
4041
/** @type {any} */
4142
var component_function = DEV ? component_context?.function : null;
4243

43-
/** @type {V | Promise<V> | null} */
44-
var input;
44+
/** @type {V | Promise<V> | typeof UNINITIALIZED} */
45+
var input = UNINITIALIZED;
4546

4647
/** @type {Effect | null} */
4748
var pending_effect;
@@ -156,8 +157,8 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) {
156157
update(THEN, false);
157158
}
158159

159-
// Set the input to null, in order to disable the promise callbacks
160-
return () => (input = null);
160+
// Set the input to something else, in order to disable the promise callbacks
161+
return () => (input = UNINITIALIZED);
161162
});
162163

163164
if (hydrating) {
Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
import { flushSync } from 'svelte';
2-
import { test } from '../../test';
2+
import { ok, test } from '../../test';
33

44
export default test({
55
compileOptions: {
66
dev: true
77
},
8-
test() {}
8+
test({ assert, target }) {
9+
const [btn1, btn2] = target.querySelectorAll('button');
10+
const p = target.querySelector('p');
11+
ok(p);
12+
13+
assert.htmlEqual(p.outerHTML, `<p></p>`);
14+
15+
btn1.click();
16+
flushSync();
17+
assert.htmlEqual(p.outerHTML, `<p>1</p>`);
18+
19+
btn2.click();
20+
flushSync();
21+
assert.htmlEqual(p.outerHTML, `<p></p>`);
22+
23+
btn1.click();
24+
flushSync();
25+
assert.htmlEqual(p.outerHTML, `<p>1</p>`);
26+
}
927
});
Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
<script>
2-
let count = $state(43);
2+
let count = $state();
33
</script>
44

5-
{#await count}
6-
loading
7-
{:then count}
8-
{count}
9-
{/await}
5+
<button onclick={() => count = 1}>number</button>
6+
<button onclick={() => count = null}>nullify</button>
7+
8+
<p>
9+
{#await count}
10+
loading
11+
{:then count}
12+
{count}
13+
{/await}
14+
</p>

0 commit comments

Comments
 (0)