svelte icon indicating copy to clipboard operation
svelte copied to clipboard

`input type="number"` bindings can be `null` and `undefined`

Open probablykasper opened this issue 3 years ago • 7 comments

Describe the bug

The documentation says:

If the input is empty or invalid (in the case of type="number"), the value is undefined.

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

probablykasper avatar Dec 08 '22 06:12 probablykasper

I've tried with 3 different browsers (Chrome, Edge and Firefox), all results in undefined rather than null

phamduylong avatar Feb 04 '23 17:02 phamduylong

It's undefined initially, but when emptying the input, it becomes null. Updated the REPL to make that clearer

probablykasper avatar Feb 05 '23 00:02 probablykasper

This bug appears in Svelte 5 too: https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE0WOzQrCMBCEX2VZPLRQ6D2mAQ8-gUfjoT9bDbRrSDaFEvruEhE8ft_AzGSc3UIR1T0j9yuhwov32KDsvkDcaBHCBuM7hbEYHcfgvBjLVhYSYOjgFKUXquqzZd3-c9beXFcvO8iLwLFPonTrjWX9BSgjnUVO60DBIgyOJ7X1S6Iu89H-OgKZcg06yDcJjp8V14dui7eMDa7vyc2OJlQSEh2P4wPqcR_a1QAAAA==

probablykasper avatar Aug 26 '24 07:08 probablykasper

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.

brunnerh avatar Aug 26 '24 08:08 brunnerh

The docs were indeed updated to null (#9941).

Is it standard behaviour that undefined can be bound to a value that cannot be undefined?

probablykasper avatar Aug 26 '24 08:08 probablykasper

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}

REPL

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 ''.

brunnerh avatar Aug 26 '24 09:08 brunnerh

Yep, that makes sense. The input's value is null while the bound variable is undefined, aka the binding isn't working.

probablykasper avatar Aug 26 '24 09:08 probablykasper