Skip to content

Non intuitive $bindable default value behavior #14254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dm-de opened this issue Nov 10, 2024 · 6 comments
Closed

Non intuitive $bindable default value behavior #14254

dm-de opened this issue Nov 10, 2024 · 6 comments

Comments

@dm-de
Copy link

dm-de commented Nov 10, 2024

Describe the problem

While beta testing and after porting a Svelte 4 project, I would like to share these experiences.

It looks like the default value of $bindable is useless.

Example 1

Error: props_invalid_value Cannot do bind:value={undefined} when value has a fallback value

Input.svelte has a $bindable with default value ''
and state in App.svelte has undefined value.
But this is, what I like to use... for example to fill data in an empty object.

The message: bind:value={undefined} feels not correct.
I use a bind:value - and this is a shortcode for bind:value={value}

It is hard to find the error, because $bindable-line is marked as error and not the parents line.

.

But this error come up only at initial phase.
If you see my Example 2, you will note that it is possible to set undefined later.
This is not intuitive. Why I can not use undefined first - but can set undefined later?

.

Here is my Example 3 - where I don't use this useless $bindable default anymore. Instead I use an extra $effect to set right default value. It is no more possible to set undefined, because Input force a default empty string in that case.

I believe that other people will expect the same behavior like before with Svelte 4.
Otherwise it is not intuitive and require extra $effects to fix.

Describe the proposed solution

see above

Importance

would make my life easier

@dummdidumm
Copy link
Member

This is a known breaking changes in runes mode, soo the link for an explanation: https://svelte.dev/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-Bindings-need-to-be-explicitly-defined-using-$bindable()

Closing because this works as designed

@dummdidumm dummdidumm closed this as not planned Won't fix, can't repro, duplicate, stale Nov 12, 2024
@dm-de
Copy link
Author

dm-de commented Nov 12, 2024

It's a pity.

Now, I removed every single $bindable default value from my source code and added additional $effect everywhere.
Because, as I explained, it is unusable and it makes no sense.

I think it is not to late rethink this design, because v5 is very fresh...
But this is up to you.

@webJose
Copy link
Contributor

webJose commented Nov 13, 2024

I have been bitten by this problem too. The effect was a completely blank page instead of an error popping up anywhere. In the REPL, we see the error referenced in this issue, but in a Sveltekit project the error doesn't show up.

@webJose
Copy link
Contributor

webJose commented Nov 13, 2024

As I understand the documentation, one is doomed to not use default values. They are useless: The consumers will still need to know this default value as a minimum if they want "default" behavior, making the use of default values worthless.

@ryanatkn
Copy link
Contributor

ryanatkn commented Nov 13, 2024

Past discussion: #9764

I think the following is functionally equivalent from the consumer's POV as if bindable defaults were allowed, opting into the wasteful render cycle mentioned in the docs, and also working in SSR:

playground

let {value = $bindable()} = $props();

const set_default = () => {
	if (value === undefined) value = 'default value';
};

set_default();
$effect.pre(set_default);

(also I know it's discouraged to respond to closed issues, and I would like to be corrected if I'm wrong here, but it seems like this is an example of an exception for topics where users want to add information without either going silent or continuously re-litigating in new issues, with the understanding that their comments may go unseen and unaddressed)

@dm-de
Copy link
Author

dm-de commented Nov 13, 2024

It's being made out here as if this update is a bad thing.

In fact, it can be a desirable behavior.

Doesn't the update only happen when a value is “undefined”? So if you think you can do without such a wasteful update, all you have to do is set a value with bind.

Furthermore, I think it would be a option for compiler setting. Similar to runes: true in svelte.config.js.

Svelte compiler could then automatically generate such extra code.
I would use this option.


I would like to give you an example.

I have an account component.

The data is stored in form and this is empty at the beginning:

let form = {}

When uploading the data, this form is sent.

When loading the data, the form does not contain all the data (no password).

With update from Svelte 4 to 5 it did not work anymore.

And although I had checked all input's that they have bind. Although I had predefined all data in form object.

I had overlooked the fact that no password is sent when loading.

And that took some time to find the error. And this is frustrating because such over-optimization it is unnecessary for a form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants