Quantcast
Channel: Programming Rants
Viewing all articles
Browse latest Browse all 204

Svelte Tutorial 4: Logic (Branch, Loop, and Async)

$
0
0
Svelte offer ways to express logic, which HTML doesn't. Rule of the thumb is
{# to start logic block (if, each, await)
{: for continuation logic block (else, then, catch)
{/ to close logic block

If Blocks (decision/branch)


We use tag {#if condition}{/if}  to do logical if. Here is some code example:

<script>
let user = { loggedIn: false };function toggle() {
user.loggedIn = !user.loggedIn;
}
</script>

{#if user.loggedIn}
<button on:click={toggle}>
Log out
</button>
{/if}

{#if !user.loggedIn}
<button on:click={toggle}>
Log in
</button>
{/if}

Else


Use {:else} to do logical else. If else block will look like this

{#if [condition]}
  ...
{:else}
  ...
{/if}

A # character always indicates a block opening tag. A / character always indicates a block closing tag. A : character, as in {:else}, indicates a block continuation tag.

Else if


You can chain multiple condition using else if like this:

{#if [condition]}
  ...
{:else if [condition]}
  ...
{:else}
  ...
{/if}

Each  (looping)


If you need to loop over lists of data, use an each block:

<script>
let cats = [
{ id: 'J---aiyznGQ', name: 'Keyboard Cat' },
{ id: 'z_AbfPXTKms', name: 'Maru' },
{ id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }
];
</script>

<h1>The Famous Cats of YouTube</h1>
<ul>
{#each cats as cat}
<li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
{cat.name}
</a></li>
{/each}
</ul>

You can get the current index as a second argument, like so:

{#each cats as cat, i}
<li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
{i + 1}: {cat.name}
</a></li>
{/each}
If you prefer, you can use destructuring — each cats as { id, name }— and replace cat.id and cat.name with id and name.

{#each cats as { id, name }, i}
<li><a target="_blank" href="https://www.youtube.com/watch?v={id}">
{i + 1}: {name}
</a></li>
{/each}

Keyed each


When you add or remove something from each block, it will remove or add at the last position of data. But sometimes it's not what we want, for example when you use array operation slice(1), you want to remove first data without re-rendering/reset the rest. So in order to match the perspective we use keyed each to mark each generated object as unique like this:

{#each things as thing (thing.id)}
<Thing current={thing.color}/>
{/each}

instead of:

{#each things as thing}
<Thing current={thing.color}/>
{/each}

so when we remove first position of array, the component that is removed in the each block is also the first one not the last one, for interactive example you can check this https://svelte.dev/tutorial/keyed-each-blocks

Await Block (async calls)


Most web applications have to deal with asynchronous data at some point. Svelte makes it easy to await the value of  directly in your markup. Here is the example of await block:

{#await promise}
<p>...waiting</p>
{:then number}
<p>The number is {number}</p>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}

For example:

<script>
  let promise = exampleAsync();
  async function exampleAsnyc() {
    await new Promise(r => setTimeout(r, 2000)); // eg. hitting certain API
    return Math.random()

  }
  function onClick() { promise = exampleAsync(); }
</script>
<button on:click="onClick">Click Me!</button>

Viewing all articles
Browse latest Browse all 204

Trending Articles