`input type="number"` bindings can be `null` and `undefined`
Describe the bug
The documentation says:
If the input is empty or invalid (in the case of
type="number"), the value isundefined.
When the value is initialized, it is indeed undefined. However, when later emptying the input, it becomes null. In previous versions it did become undefined - https://github.com/sveltejs/svelte/issues/1701 seems to be what changed it in order to fix a warning.
Reproduction
https://svelte.dev/repl/58ce9182263245d0b646d115d7e5e1e7?version=3.54.0
Logs
No response
System Info
System:
OS: macOS 10.15.7
CPU: (8) x64 Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz
Memory: 1.92 GB / 32.00 GB
Shell: 3.5.1 - /usr/local/bin/fish
Binaries:
npm: 8.19.2 - ~/Library/Application Support/Volta/tools/image/node/18.12.1/bin/npm
Browsers:
Brave Browser: 107.1.45.131
Chrome: 108.0.5359.94
Firefox: 107.0
Firefox Developer Edition: 108.0
Safari: 15.6.1
npmPackages:
svelte: ^3.54.0 => 3.54.0
Severity
annoyance
I've tried with 3 different browsers (Chrome, Edge and Firefox), all results in undefined rather than null
It's undefined initially, but when emptying the input, it becomes null. Updated the REPL to make that clearer
This bug appears in Svelte 5 too: https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE0WOzQrCMBCEX2VZPLRQ6D2mAQ8-gUfjoT9bDbRrSDaFEvruEhE8ft_AzGSc3UIR1T0j9yuhwov32KDsvkDcaBHCBuM7hbEYHcfgvBjLVhYSYOjgFKUXquqzZd3-c9beXFcvO8iLwLFPonTrjWX9BSgjnUVO60DBIgyOJ7X1S6Iu89H-OgKZcg06yDcJjp8V14dui7eMDa7vyc2OJlQSEh2P4wPqcR_a1QAAAA==
To me this feels more like a documentation issue - validity does not change the bound value either (unless the docs talk about some kind of validity I am unaware of).
If you want a more consistent value, initialize the state to null.
Having it initially as undefined can otherwise be used to tell whether the input has been changed yet since it will either be a number or null after interaction.
The docs were indeed updated to null (#9941).
Is it standard behaviour that undefined can be bound to a value that cannot be undefined?
undefined when passed in for the most part means "ignore".
E.g. with fallback values, the fallback will apply.
<script>
import Component from './Component.svelte';
let value = undefined;
</script>
<Component {value} />
<!-- Component.svelte -->
<script>
export let value = 1;
</script>
Value: {value}
There is a change in Svelte 5 that when a binding is used, undefined is no longer allowed when a fallback exists (REPL).
De facto the same should be true for input elements, they always have a fallback value.
For type="number" that would be null, for text-based inputs it's ''.
Yep, that makes sense. The input's value is null while the bound variable is undefined, aka the binding isn't working.