From 3fa08d565cf11ac5673b5ecc74868965e2255be2 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:32:08 +0100 Subject: [PATCH] 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 --- .changeset/breezy-insects-live.md | 5 +++++ .../src/internal/client/dom/blocks/await.js | 9 ++++---- .../samples/await-non-promise/_config.js | 22 +++++++++++++++++-- .../samples/await-non-promise/main.svelte | 17 +++++++++----- 4 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 .changeset/breezy-insects-live.md diff --git a/.changeset/breezy-insects-live.md b/.changeset/breezy-insects-live.md new file mode 100644 index 000000000000..8b86fab6be88 --- /dev/null +++ b/.changeset/breezy-insects-live.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: show `:then` block for `null/undefined` value diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index 29ef15452fdf..62b2e4dd0cda 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -14,6 +14,7 @@ import { } from '../../runtime.js'; import { hydrate_next, hydrate_node, hydrating } from '../hydration.js'; import { queue_micro_task } from '../task.js'; +import { UNINITIALIZED } from '../../../../constants.js'; const PENDING = 0; const THEN = 1; @@ -40,8 +41,8 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) { /** @type {any} */ var component_function = DEV ? component_context?.function : null; - /** @type {V | Promise | null} */ - var input; + /** @type {V | Promise | typeof UNINITIALIZED} */ + var input = UNINITIALIZED; /** @type {Effect | null} */ var pending_effect; @@ -156,8 +157,8 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) { update(THEN, false); } - // Set the input to null, in order to disable the promise callbacks - return () => (input = null); + // Set the input to something else, in order to disable the promise callbacks + return () => (input = UNINITIALIZED); }); if (hydrating) { diff --git a/packages/svelte/tests/runtime-runes/samples/await-non-promise/_config.js b/packages/svelte/tests/runtime-runes/samples/await-non-promise/_config.js index 14dac303506d..882742f73175 100644 --- a/packages/svelte/tests/runtime-runes/samples/await-non-promise/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/await-non-promise/_config.js @@ -1,9 +1,27 @@ import { flushSync } from 'svelte'; -import { test } from '../../test'; +import { ok, test } from '../../test'; export default test({ compileOptions: { dev: true }, - test() {} + test({ assert, target }) { + const [btn1, btn2] = target.querySelectorAll('button'); + const p = target.querySelector('p'); + ok(p); + + assert.htmlEqual(p.outerHTML, `

`); + + btn1.click(); + flushSync(); + assert.htmlEqual(p.outerHTML, `

1

`); + + btn2.click(); + flushSync(); + assert.htmlEqual(p.outerHTML, `

`); + + btn1.click(); + flushSync(); + assert.htmlEqual(p.outerHTML, `

1

`); + } }); diff --git a/packages/svelte/tests/runtime-runes/samples/await-non-promise/main.svelte b/packages/svelte/tests/runtime-runes/samples/await-non-promise/main.svelte index 62881ba66666..efd05f2dd2bb 100644 --- a/packages/svelte/tests/runtime-runes/samples/await-non-promise/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/await-non-promise/main.svelte @@ -1,9 +1,14 @@ -{#await count} - loading -{:then count} - {count} -{/await} \ No newline at end of file + + + +

+ {#await count} + loading + {:then count} + {count} + {/await} +