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
pull/14444/head
Simon H 1 month ago committed by GitHub
parent 9e9fb2463c
commit 3fa08d565c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: show `:then` block for `null/undefined` value

@ -14,6 +14,7 @@ import {
} from '../../runtime.js'; } from '../../runtime.js';
import { hydrate_next, hydrate_node, hydrating } from '../hydration.js'; import { hydrate_next, hydrate_node, hydrating } from '../hydration.js';
import { queue_micro_task } from '../task.js'; import { queue_micro_task } from '../task.js';
import { UNINITIALIZED } from '../../../../constants.js';
const PENDING = 0; const PENDING = 0;
const THEN = 1; const THEN = 1;
@ -40,8 +41,8 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) {
/** @type {any} */ /** @type {any} */
var component_function = DEV ? component_context?.function : null; var component_function = DEV ? component_context?.function : null;
/** @type {V | Promise<V> | null} */ /** @type {V | Promise<V> | typeof UNINITIALIZED} */
var input; var input = UNINITIALIZED;
/** @type {Effect | null} */ /** @type {Effect | null} */
var pending_effect; var pending_effect;
@ -156,8 +157,8 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) {
update(THEN, false); update(THEN, false);
} }
// Set the input to null, in order to disable the promise callbacks // Set the input to something else, in order to disable the promise callbacks
return () => (input = null); return () => (input = UNINITIALIZED);
}); });
if (hydrating) { if (hydrating) {

@ -1,9 +1,27 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { ok, test } from '../../test';
export default test({ export default test({
compileOptions: { compileOptions: {
dev: true dev: true
}, },
test() {} test({ assert, target }) {
const [btn1, btn2] = target.querySelectorAll('button');
const p = target.querySelector('p');
ok(p);
assert.htmlEqual(p.outerHTML, `<p></p>`);
btn1.click();
flushSync();
assert.htmlEqual(p.outerHTML, `<p>1</p>`);
btn2.click();
flushSync();
assert.htmlEqual(p.outerHTML, `<p></p>`);
btn1.click();
flushSync();
assert.htmlEqual(p.outerHTML, `<p>1</p>`);
}
}); });

@ -1,9 +1,14 @@
<script> <script>
let count = $state(43); let count = $state();
</script> </script>
{#await count} <button onclick={() => count = 1}>number</button>
loading <button onclick={() => count = null}>nullify</button>
{:then count}
{count} <p>
{/await} {#await count}
loading
{:then count}
{count}
{/await}
</p>

Loading…
Cancel
Save