Another Todo app with Svelte
Tags: javascript, todayilearned
Published: 2020-03-16 04:30:57

##Introduction
This article is about getting started with svelteJS.

Svelte...yes another javascript framework which is gaining some fuss. 

##How to start with svelte??

[Svelte REPL](https://svelte.dev/repl/hello-world?version=3.19.2)  is the easiest way to begin.
Click the download button to save a svelte-app.zip file to your computer and uncompress it.

Open a terminal window and set the project up...
```javascript
cd /path/to/svelte-app
npm install
```
...then start up a development server:
```javascript
npm run dev
```
This will serve your app on [localhost:5000](http://localhost:5000/) and rebuild it with [Rollup](https://rollupjs.org/guide/en/)  every time you make a change to the files in svelte-app/src.

I know there are quite a few todo apps that you will come across enroute to learning Svelte. This is a just a small implementation in my way.

Let's begin...
If you navigate to your **src** folder, you would see two files:
1) main.js
```javascript
import App from './App.svelte';

var app = new App({
	target: document.body
});

export default app;
```
2) App.svelte
```javascript
<script>
 let name = 'world';
</script>

<h1>Hello {name.toUpperCase()}!</h1>
```

Now if you check localhost:5000, you would see this,
##Hello WORLD!

Now, we will begin adding our code for todo app.
My use case: 
1) display a list of todos
2) option to add new todo
3) clear the selected or completed todo
4) display the count for remaining todos.

Create a file named **Todos.svelte** and add the following content:
```javascript
<script>
let todos = [
    {done: false, text: 'Learn React JS'},
    {done: false, text: 'Learn Angular 2+'},
    {done: false, text: 'Learn Svelte JS'},
    { done: false, text: 'finish Svelte tutorial' },
    { done: false, text: 'build an app' },
    { done: false, text: 'world domination' }
];
</script>
```
Firstly I need a list of todos, so I created an array which holds some list.
Now, I need to display this todos so I add some HTML
```javascript
{#each todos as todo}
<div>
    <input type="checkbox" checked={todo.done}/>
    <span>{todo.text}</span>
</div>   
{/each}
```
The above code iterates over the list of todos, displaying a checkbox with text.
**{#each}...{/each}** is used for iteration.

**Now we need an option to add new todo**
```javascript
<script>
....
let newTodo = ''; // to store the entered text

function add(){
    todos = [...todos, {done:false, text:newTodo}]; //concat new value to list
    newTodo = '';
}
</script>
<form on:submit|preventDefault={add}>
    <input type="text" value={newTodo} /> //storing value in newTodo
    <button type="submit">Add new</button>
</form>
...
```
I have used a form element to contain my option for adding a todo.
To mention any event handler, you would use **on:eventname={eventhandler}**
For example: on:click={handleClick} or on:submit={add}

While submitting a form , we need to prevent the default submit to stop page reload. This can be done in svelte using **pipe** followed by **preventdefault**
```javascript
<form on:submit|preventDefault={add}>
```
Go to localhost try adding a new todo item and click add new button or press enter. You will notice the new item gets added to the list.

Time to clear the completed todo.
```javascript
function clear(e){
    e.preventDefault();
    todos = todos.filter(todo => !todo.done)
}
</script>
<style>
	.done {
		opacity: 0.4;
	}
</style>
<form on:submit|preventDefault={add}>
    <input type="text" bind:value={newTodo} />
    <button type="submit" disabled={!newTodo}>Add new</button>
    <button on:click={clear}>Clear completed</button>
</form>
{#each todos as todo}
<div class:done={todo.done}>
    <input type="checkbox" bind:checked={todo.done}/>
    <span>{todo.text}</span>
</div>   
{/each}
```
I have added a class name **done** and used **class:done** to apply the class only on selected checkbox or todo.
I have also disabled the add new button when the input box is empty.
We have a clear button which on click removes the selected item(s) from the list.
Notice the bind: directive. It is like two way binding.

Last thing to do is to display the remaining todos.

###Reactivity
At the heart of Svelte is a powerful system of reactivity for keeping the DOM in sync with your application state — for example, in response to an event.

We will use this reactive declaration:
```javascript
$: remaining = todos.filter(todo => !todo.done).length;
```
Add something after " $: " which you want to test after any state change.

So, my final code for **Todos.svelte** looks like this:
```javascript
<script>
let todos = [
    {done: false, text: 'Learn React JS'},
    {done: false, text: 'Learn Angular 2+'},
    {done: false, text: 'Learn Svelte JS'},
    { done: false, text: 'finish Svelte tutorial' },
    { done: false, text: 'build an app' },
    { done: false, text: 'world domination' }
];
let newText = '';

function add(){
    todos = [...todos, {done:false, text:newText}];
    newText = '';
}

function clear(e){
    e.preventDefault();
    todos = todos.filter(todo => !todo.done)
}

$: remaining = todos.filter(todo => !todo.done).length;
</script>
<style>
	.done {
		opacity: 0.4;
	}
</style>

<div>
<h2> A simple todo app with svelte</h2>
<form on:submit|preventDefault={add}>
    <input type="text" bind:value={newText} />
    <button type="submit" disabled={!newText}>Add new</button>
    <button on:click={clear}>Clear completed</button>
</form>
<p>you have {remaining} remaining {remaining === 1? 'task': 'tasks'}</p>
{#each todos as todo}
<div class:done={todo.done}>
    <input type="checkbox" bind:checked={todo.done}/>
    <span>{todo.text}</span>
</div>   
{/each}
</div>
```
See [localhost:5000](http://localhost:5000/) and try adding new todos and clearing completed todos.

I tried a very simple use case and it is not styled. Just wanted to put forward basic working todo with minimal usecase.

Hope you followed it and got the desired result.
Cheers !!!