1

I am new to Svelte and there are things I suppose should be easy to do and yet they give me trouble. In a small Svelte app I have this HTML:

<div class="mt-5 mb-6">
   <Switch on:click={toggle} /> <span>{stat}</span>
</div>

I need to display "On" or "Off" in the span element, depending on the "state" of the switch. For this purpose, I have:

import Switch from './Switch.svelte';
let stat = 'off';
let status = false;

function toggle () {
 status = !status;
     stat = status ? "on" : "off";
}

See REPL here.

For a reason I can not understand, even though there's no error in the console, the span always shows "Off". Why?

3 Answers 3

2

You are making it too complicated. You can easily bind to the checked value of the underlying component:

<script>
    import Switch from './Switch.svelte';
    let status;
    
</script>

<div>
    <Switch bind:checked={status} /> <span>{status ? "on" : "off"}</span>
</div>

Before, you tried to listen to an click event, which your Switch component does not have, that is why it did not work. But as it is a checkbox, it has the checked property. Find more info here.

Sign up to request clarification or add additional context in comments.

4 Comments

I want to keep my HTML as clean as possible. What shall I replace the click event with?
You can replace it with the bind:checked={status}. Check it in this REPL: svelte.dev/repl/dae8a556dac44ac1b48a949dd2ae61f2?version=3.23.2
Thanks! Have a look at this one too.
Hey, the link goes to this page. I also see from the other answer, that I did not understand your second question about the tidy html. I would have done it the same way as @RazvanZamfir
2

Another version, with no logic in the HTML (and all of it inside the <script> tag):

<script>
    import Switch from '../ui/Switch.svelte';
    let stat = 'off';
    let status = false;
    $:stat = status ? "On" : "Off"; 
</script>

<div>
    <Switch bind:checked={status} /> <span>{stat}</span>
</div>

Comments

1

Another version, using the event dispatcher from the child component to emit the click event to the parent:

//Switch.svelte
<script>
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();
</script>

<label class="switch">
  <input type="checkbox" on:click="{() => dispatch('toggle')}"/>
  <span class="slider" />
</label>

...

//App.svelte
<script>
    import Switch from './Switch.svelte';
    let stat = 'off';
    let status = false;
    
    function toggle () {
     status = !status;
         stat = status ? "on" : "off";
  }
</script>

<div class="mt-5 mb-6">
    <Switch on:toggle={toggle} /> <span>{stat}</span>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.