Nothing special Svelte todo app

Nothing special Svelte todo app

·

3 min read

Featured on Hashnode

image.png

Svelte

I just wanted to give Svelte a try. This is just yet another todo app with Svelte and nothing more than that.

Hello Todo!

The code

Todo.svelte

I put on the simple code which just works -- Isn't there syntax highlight for Svelte?

<script>
  let newTask = "";
  let todos = [];

  let newId = () => { return Date.now().toString(36) } 

  function add(task) {
    todos = [...todos, {id: newId(), name: task, done: false}] // ❶
  }

  function done(id) {
    console.log('done called')
    let result = todos.map(todo => {
      if (todo.id == id){ todo.done = true }
      return todo
    });
    todos = result; // ❷
  }

  $: activeTodos = todos.filter(function(todo){ // ❸
    return (todo.done == false)
  });
</script>

<main>
  <h1>HELLO TODO!</h1>
  <div class="container">
    <form>
      <div class="row">
        <div class="two-thirds column">
          <input class="u-full-width" type="text" placeholder="Add new task" bind:value={newTask}>
        </div>
        <div class="one-third column"><input type="button" value="add" on:click={add(newTask)}></div>
      </div>
    </form>
    {#if activeTodos.length === 0} <!-- ❹ -->
      <h3>YOU HAVE NO TASK!</h3>
    {:else}
      <table class="u-full-width">
        <thead>
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody>
          {#each activeTodos as todo} <!-- ❺ -->
            <tr>
              <td>{todo.id}</td>
              <td>{todo.name}</td>
              <td><input type="button" value="done!" on:click={done(todo.id)}></td>
            </tr>
          {/each}
        </tbody>
      </table>
    {/if}
  </div>
</main>

<style>
  main {
    text-align: center;
    padding: 1em;
    max-width: 240px;
  }

  h1 {
    color: #ff3e00;
    text-transform: uppercase;
    font-size: 4em;
    font-weight: 100;
    margin-bottom: 1.5em;
  }

  h3 {
    color: gray;
    text-transform: uppercase;
    font-size: 2em;
    font-weight: 150;
    margin-top: 3.5em;
  }

  @media (min-width: 640px) {
    main {
      max-width: none;
    }
  }
</style>

Adding short description for the numbers in the code above:

  1. You can use the todos = [...todos, {id: newId(), name: task, done: false}] like an idiom to make it reactive. There is conditions which make a code reactive in Svelte for example, todo.push({id: newId(), name: task, done: false}) can not be reactive. Official site says:

    Because Svelte's reactivity is triggered by assignments, using array methods like push and splice won't automatically cause updates. For example, clicking the button doesn't do anything

  2. todos = result; This is also for making it reactive.

  3. $: is a javascript label. It indicate the following statements will be recalculated(reactive). Making change on todos will recalculate activeTodos.
  4. You can use if statement in a template.
  5. Also you can create loop with each.

main.js

Import Todo.svelte in main.js

import Todo from './Todo.svelte';

const app = new Todo({
 target: document.body,
});

export default app;

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset='utf-8'>
  <meta name='viewport' content='width=device-width,initial-scale=1'>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
  <link rel="preconnect" href="https://fonts.gstatic.com">

  <title>Todo</title>

  <link rel='icon' type='image/png' href='/favicon.png'>
  <link rel='stylesheet' href='/global.css'>
  <link rel='stylesheet' href='/build/bundle.css'>

  <script defer src='/build/bundle.js'></script>
</head>
<body></body>
</html>

That's it. It uses skelton.css for UI framework

Thoughts

Overall, the development experience was pretty good. Svelte is more like Vue than I thought, it is pretty much the same as a single file component of Vue, so people who have worked with Vue will feel right at home. I felt that Svelte allows you to write more raw Javascript than Vue, which is better as well.