svelte icon indicating copy to clipboard operation
svelte copied to clipboard

camelCased variable names are not reactive.

Open stanoychev opened this issue 3 years ago • 6 comments

Describe the bug

Hello. This is my first bug report ever on github, so if I`m doing it wrong please excuse me. It seems that svelte is not handling very well the camelCased variables.

<svelte:options tag='test-a'/> 
<script>
	export let variableName = "world";
</script>

<main>
	<h1>Hello {variableName}!</h1> //Hello world!
</main>

but, when I use the element like

<test-a
	id = 'test-a'
	variableName = 'test'>
</test-a>

I expected "Hello test!", but it stays on "Hello world!" and on the console window we have a message

< test-a > was created with unknown prop variableName

Another thing is, calling document.getElementById('test-a').setAttribute('variableName', 'from attribute'); I expected < h1 > to change to "Hello from attribute!", but it stays on "Hello world!". If I type document.getElementById('test-a').getAttribute('variableName'); it returns 'from attribute', and indeed on the html inspector window we can observe that the attribute is updated: < test-a id="test-a" variableName="from attribute" >, but inside the rendered element it stays on < h1 >Hello world!< /h1 >. Another approach is if I call document.getElementById('test-a').variableName = 'from attribute'; the h1 gets updated correctly to < h1 >Hello from attribute!< /h1 > (the asociated attribute value stays unupdated < test-a id="test-a" variableName="world" >).

In the above example if "variableName" is lowercased to "variablename" everithing works fine.

(Question 1) Is this expected behaviour? Am I using this right and how is the correct way to use it? In the documentation I didn`t find anything that says something like "variable names must be always lowercased".

For me it seems that the root cause is attaching the update logic of the variables to the attributes names, which are now automaticaly lowercased, causing mismatch between variable name string "variableName" and it`s subscribtion name string "variablename", resulting in not updating.

(Question 2) Is there any compiler option to set to handle this, npm package or any other magic we can use? The camelCase naming is important for our project

Reproduction

  1. Create custom element
<svelte:options tag='test-a'/> 
<script>
	export let variableName = "world";
</script>

<main>
	<h1>Hello {variableName}!</h1>
</main>
  1. use it like
<test-a
	id = 'test-a'
	variableName = 'test'>
</test-a>

Expected h1: "Hello test!" Actual result: "Hello world!"

  1. Navigate to the web browser's console and type document.getElementById('test-a').setAttribute('variableName', 'from attribute'); Expected h1: "Hello from attribute!" Actual result: "Hello world!"

Logs

No response

System Info

Windows 10, web browser agnostic

Severity

annoyance

stanoychev avatar Mar 21 '22 11:03 stanoychev

@stanoychev is this specifically when used as web-components? Camel case variables definitely work fine in "normal" use: https://svelte.dev/repl/827e19b813e84e348b1bfb0c5d08e3dd?version=3.46.4

Crisfole avatar Mar 22 '22 17:03 Crisfole

related https://github.com/sveltejs/svelte/issues/3919

mdynnl avatar Mar 23 '22 17:03 mdynnl

@stanoychev is this specifically when used as web-components? Camel case variables definitely work fine in "normal" use: https://svelte.dev/repl/827e19b813e84e348b1bfb0c5d08e3dd?version=3.46.4

Thank you for replaying. Unfortunately the online compiler doesn't work with custom elements / web-components 😐. I tried to do something here: https://svelte.dev/repl/2629cec1aec3414abe2d623fa51d6506?version=3.46.4 but the behavior is different than on my computer, when I run "npm run dev" 😐.

So I transferred the code into local repository, got carried away and uploaded it here if anyone wants to check it https://github.com/NikolaStanoychev/svelte_camelCase It shows the different behavior between camelCased variable and lowercased one.

To run it it`s the usual drill: git clone, npm i, npm run dev, click the buttons (once)

NikolaStanoychev avatar Mar 27 '22 00:03 NikolaStanoychev

There are a lot of issues around how svelte components behave when compiled to web-components and one of those issues is variable naming: https://github.com/sveltejs/svelte/issues/3852. There's a plugin that might help: https://github.com/roonie007/vite-plugin-svelte-kebab-props

abdo643-HULK avatar Apr 10 '22 13:04 abdo643-HULK

I think there should be a way to specify the attribute name for a variable.

I'm not sure what the best way to do this is. Maybe a comment?

// svelte:attribute "my-custom-attribute"
export let myCustomAttribute = 1;

This leaves no ambiguity for casing.

TheCymaera avatar Nov 05 '22 12:11 TheCymaera

This isn't legal JS, so it won't fly, but we already have renamed exports.

let myCustomAttribute = 1;
export { myCustomAttribute as "my-custom-attribute" };
//NOT LEGAL because rename isn't a valid js identifier.

This could be resolved with module level exports for renaming, but that feels super icky.

<script context="module">
  export const Params = {
    'my-custom-attribute': 'myCustomAttribute'
  };
</script>

Crisfole avatar Nov 30 '22 15:11 Crisfole

Closing as duplicate of #5184

dummdidumm avatar Mar 30 '23 16:03 dummdidumm