camelCased variable names are not reactive.
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
- Create custom element
<svelte:options tag='test-a'/>
<script>
export let variableName = "world";
</script>
<main>
<h1>Hello {variableName}!</h1>
</main>
- use it like
<test-a
id = 'test-a'
variableName = 'test'>
</test-a>
Expected h1: "Hello test!" Actual result: "Hello world!"
- 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 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
related https://github.com/sveltejs/svelte/issues/3919
@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)
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
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.
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>
Closing as duplicate of #5184