Conditional and List Rendering
Svelte handles conditionals and lists with logic blocks — special {#...} markers in the markup, closed with {/...}. This is a distinct style from all three other frameworks: not JavaScript-in-JSX (React), not directives-on-elements (Vue/Angular), but dedicated block syntax that reads almost like a templating language. Svelte even has a block for handling promises directly, which the others lack.
{#if} / {:else if} / {:else}
An {#if} block conditionally renders its contents, with optional {:else if} and {:else} branches. The opening tag uses #, continuation branches use :, and the close uses / — a consistent convention across all Svelte blocks. Like Angular's @if and Vue's v-if, a false branch genuinely removes its elements from the DOM. The whole {#if}/{:else if}/{:else} chain cleanly handles the loading/error/success pattern.
{#each} — Rendering a List
{#each items as item} repeats its contents once per array entry — Svelte's .map() equivalent. For lists that change (items added, removed, reordered), you should provide a key in parentheses so Svelte can track each item efficiently — the same role as React's key, Vue's :key, and Angular's track:
The (todo.id) after the item is the key. Unlike Angular's mandatory track, it's optional in Svelte — but strongly recommended for any list that mutates, for exactly the same correctness reasons.
{#each} with Index and an Empty Fallback
A second variable after the item gives the index — todo, index. And neatly, {#each} supports its own {:else} branch, rendered when the array is empty — handling the "empty list" case inline, the same convenience as Angular's @empty but built right into the each-block.
{#await} — Rendering a Promise Directly
This block has no equivalent in the other frameworks. {#await promise} renders the three states of a Promise directly in the markup: pending (before {:then}), resolved ({:then data} with the result), and rejected ({:catch error}). The loading/error/success pattern that took manual status state in every other framework's data-fetching is handled declaratively here, with the promise itself as the source of truth. (The {:then} and {:catch} branches are both optional if you only care about some states.)
isLoading/error/data state by hand (or reach for a library like React Query). Svelte bakes the three-state promise lifecycle into a template block. Pass a fetch promise straight in — {#await fetch(url).then(r => r.json())} — and the markup handles all three states with no extra state variables at all.
{#each} over a list that gets reordered or filtered can attach the wrong state to the wrong item — the same class of bug a missing React key causes. Add (item.id) to any list that changes.
| Svelte | Vue | Angular | React |
|---|---|---|---|
| {#if} / {:else if} / {:else} | v-if / v-else-if / v-else | @if / @else if | ternary / && |
| {#each x as item (id)} | v-for + :key | @for + track | .map() + key |
| {#each ...}{:else} | separate check | @empty | separate check |
| {#await} / {:then} / {:catch} | — | — | — (or React Query/Suspense) |
Coding Challenges
Build a component with a status $state ("loading"/"error"/"success") cycled by a button, using {#if}/{:else if}/{:else} to show different content per status.
📄 View solutionGiven a $state array of objects ({ id, name }), render them with {#each} (keyed on id) in a numbered list using the index, and include a {:else} branch showing "No items" when the array is cleared by a button.
📄 View solutionBuild a component that fetches from any free public API into a promise and renders it with {#await}/{:then}/{:catch} — showing a loading message, the result on success, and an error message on failure, with no manual status state.
📄 View solutionChapter 5 Quick Reference
- {#if} / {:else if} / {:else} / {/if} — conditional rendering;
#opens,:continues,/closes - {#each items as item (id)} — list rendering; the
(id)key is optional but advised for dynamic lists - {#each items as item, index} — also exposes the index
- {#each ...}{:else} — built-in empty-list fallback (= Angular's
@empty) - {#await promise}{:then data}{:catch error} — render a Promise's three states inline (unique to Svelte)
- Key any list that gets reordered/filtered, the same discipline as React's
key - Next chapter: components and props ($props)