Lesson 4
Control Flow in Svelte: Using `#if`, `#else-if`, and `#else`
Introduction to Control Flow in Svelte

Welcome back! In the previous lesson, you learned how to use Svelte’s reactivity model with runes like $state and $derived to create dynamic and responsive components. Now, we’ll explore another essential feature of Svelte: control flow. Control flow allows you to conditionally render parts of your UI based on specific conditions, making your applications more interactive and user-friendly.

In this lesson, we’ll focus on three key control flow structures: #if, #else-if, and #else. These blocks enable you to show or hide content dynamically, depending on the state of your application. For example, you might want to display a welcome message only if a user is logged in or show different content based on their role.

To keep things simple, we’ll build on the reactivity concepts you’ve already learned, using $state to manage the conditions that control what gets rendered. Let’s dive in and see how these control flow blocks work in practice!

Understanding the `#if` Block

The #if block is the simplest form of control flow in Svelte. It allows you to conditionally render content based on a boolean expression. If the expression evaluates to true, the content inside the #if block is displayed; otherwise, it’s hidden.

Here’s a basic example:

svelte
1<script lang="ts"> 2 let isVisible = $state(false); 3</script> 4 5{#if isVisible} 6 <p>This message is visible!</p> 7{/if} 8 9<button onclick={() => isVisible = !isVisible}> 10 Toggle Visibility 11</button>

In this example, the isVisible state variable controls whether the paragraph is displayed. Clicking the button toggles the value of isVisible, showing or hiding the message.

This is a simple yet powerful way to control what your users see based on the state of your application.

Adding `#else-if` and `#else` Blocks

While #if is great for simple conditions, you’ll often need to handle multiple conditions. This is where #else-if and #else come in. The #else-if block allows you to check additional conditions if the previous #if or #else-if block evaluates to false. The #else block provides a fallback for when none of the conditions are met.

Let’s look at an example where we display different messages based on a user’s role:

svelte
1<script lang="ts"> 2 let userRole = $state<'admin' | 'editor' | 'viewer' | null>(null); 3</script> 4 5{#if userRole === 'admin'} 6 <p>Welcome, Admin! You have full access.</p> 7{:else if userRole === 'editor'} 8 <p>Welcome, Editor! You can create and edit content.</p> 9{:else if userRole === 'viewer'} 10 <p>Welcome, Viewer! You can view content.</p> 11{:else} 12 <p>Please log in to access the system.</p> 13{/if}

In this example, the message displayed depends on the value of userRole. If userRole is null, the #else block ensures a default message is shown. This structure makes it easy to handle complex logic while keeping your code clean and readable.

Real-World Example: Login System

Now that you understand the basics of control flow, let’s apply these concepts to a real-world example: a login system. The code provided earlier demonstrates how to use #if, #else-if, and #else to manage login states and user roles. Here’s the code again for reference:

svelte
1<script lang="ts"> 2 let isLoggedIn = $state(false); 3 let userRole = $state<'admin' | 'editor' | 'viewer' | null>(null); 4 5 function login(role: 'admin' | 'editor' | 'viewer') { 6 isLoggedIn = true; 7 userRole = role; 8 } 9 10 function logout() { 11 isLoggedIn = false; 12 userRole = null; 13 } 14</script> 15 16{#if !isLoggedIn} 17 <h1>Welcome! Please log in.</h1> 18 <button onclick={() => login('viewer')}>Log in as Viewer</button> 19 <button onclick={() => login('editor')}>Log in as Editor</button> 20 <button onclick={() => login('admin')}>Log in as Admin</button> 21{:else} 22 {#if userRole === 'admin'} 23 <h1>Welcome, Admin! You have full access.</h1> 24 {:else if userRole === 'editor'} 25 <h1>Welcome, Editor! You can create and edit content.</h1> 26 {:else if userRole === 'viewer'} 27 <h1>Welcome, Viewer! You can view content.</h1> 28 {/if} 29 <button onclick={logout}>Log out</button> 30{/if} 31 32<style> 33 h1 { 34 color: green; 35 } 36 button { 37 padding: 10px; 38 margin: 5px; 39 cursor: pointer; 40 } 41</style>

In this example, the #if block checks whether the user is logged in. If not, it displays a welcome message and login buttons. Once logged in, the #else block shows a personalized message based on the user’s role. The logout button allows the user to log out, resetting the state.

This example demonstrates how control flow can be used to create a dynamic and interactive user interface.

Summary and Preparation for Practice

In this lesson, you learned how to use control flow structures like #if, #else-if, and #else to conditionally render content in Svelte. These blocks are essential for building dynamic and responsive applications, allowing you to show or hide content based on the state of your app.

You also saw how these concepts can be applied to a real-world example, such as a login system. By combining control flow with Svelte’s reactivity model, you can create powerful and intuitive user interfaces.

In the upcoming practice exercises, you’ll have the opportunity to experiment with these concepts and build your own dynamic components. Try modifying the login system example or creating new components that use control flow to manage different states. Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.