#svelte #javascript #frontend

Day 3: Logic Blocks

Welcome to Day 3. We have state. Now we need to show or hide things based on that state.

Svelte logic blocks look like {#name} ... {/name}.

1. Conditionals: {#if}

<script lang="ts">
  let isLoggedIn = $state(false);
</script>

<button onclick={() => isLoggedIn = !isLoggedIn}>
  Toggle Login
</button>

{#if isLoggedIn}
  <p>Welcome back, user!</p>
{:else}
  <p>Please log in.</p>
{/if}

2. Loops: {#each}

Iterate over arrays.

<script>
  let cats = $state([
    { id: 'j3k', name: 'Whiskers' },
    { id: 'f8g', name: 'Mittens' }
  ]);
</script>

<ul>
  {#each cats as cat (cat.id)}
    <li>{cat.name}</li>
  {/each}
</ul>

Keyed Each: Notice (cat.id). This tells Svelte how to identify items uniquely, crucial for performance and animation.

3. Async: {#await}

Svelte can handle promises directly in the markup!

<script>
  async function rollDice() {
    return Math.floor(Math.random() * 6) + 1;
  }
  
  let promise = $state(rollDice());
</script>

<button onclick={() => promise = rollDice()}>Roll again</button>

{#await promise}
  <p>Rolling...</p>
{:then result}
  <p>You rolled a {result}!</p>
{:catch error}
  <p>Something broke: {error.message}</p>
{/await}

Challenge for Day 3

  1. Create a list of tasks (id, text, done).
  2. Render them with {#each}.
  3. Add a standard checkbox input <input type="checkbox" bind:checked={task.done} /> (we’ll cover bindings more later, but try it!).
  4. Use {#if} to conditionally cross out the text <del> if done.

Solution:

<script lang="ts">
  let tasks = $state([
    { id: 1, text: "Learn Svelte", done: true },
    { id: 2, text: "Build App", done: false }
  ]);
</script>

<ul>
  {#each tasks as task (task.id)}
    <li>
      <input type="checkbox" bind:checked={task.done} />
      
      {#if task.done}
        <del>{task.text}</del>
      {:else}
        <span>{task.text}</span>
      {/if}
    </li>
  {/each}
</ul>

You master the flow! Tomorrow we dive deeper into Events and how users interact with your app.