We have already covered the Writable and Readable store in the previous articles. In this article, we will learn how to make use of derived store from Svelte. If you want a refresher on those topic, have a look at the following two topics
https://www.eternaldev.com/blog/introduction-to-svelte-stores/
https://www.eternaldev.com/blog/introduction-to-svelte-readable-store/
When you want to perform on client side filtering based on user input, then using a derived store can be a good option. Store the actual data in the store and then use another derived store to store just the filtered options.
In general, if you want to derive another data from a store value and want that value to update every time the store updates, you can use derived store
Let’s skip these generic definition and see a practical example. We will implement a client side search on a list of post we have fetched.
Building a home page which will have a list of post and then a search box to filter the post based on the search. We will pull the data from the Placeholder API which will return a total of 200 posts. When the user enter the text in the search box, we will use the derived store to filter the posts and show the filtered post to the user.
Creating a derived store can be done after import derived
from svelte/store
. It needs to be dependent on either a writable or readable store and the value of this store is recalculated when one of its dependency changes
Create a new file called postStore.svelte
inside the new folder called `store
import { writable, derived} from "svelte/store";
import type { Writable } from "svelte/store";
type Post = {
title: string;
body: string;
}
export const allPostStore: Writable<Post[]> = writable([]);
export const filteredText: Writable<string> = writable("");
export const filteredPostStore = derived([allPostStore, filteredText], ([$allPostStore, $filteredText]) => {
return $allPostStore.filter((item) => item.title.includes($filteredText));
})
Let’s breakdown the above code
svelte/store
Post
type which fits the response form the API (placeholder post API)allPostStore
writable store which will be used to store the list of post from the APIfilteredText
writable store which will store the value of the text entered in Search input textCreate a new file called PostDisplay.svelte
and add the following code
<script lang="ts">
import {onMount} from "svelte";
import {allPostStore, filteredPostStore, filteredText} from '../store/postStore';
let postPromise;
onMount(() => {
postPromise = fetch('https://jsonplaceholder.typicode.com/posts').then((data) => data.json()).then((post) => {
$allPostStore = post;
});
})
</script>
../store/postStore
. This will give us access to the store to read and write contentonMount
life cycle method which will be called on the component being rendered on the screen$allPostStore
store.Now we have access to all the post. When the user enters the search text, we can do front-end filtering of the list and display only the post which match the search text. This is where our derived store helps.
We store the post value in the $allPostStore
but we can use the derived store variable to display the post. This means that the original list of all the post is not disturbed and we get a new filtered list every time the search text changes. Sweet!
<h1>Posts</h1>
{#await postPromise}
<h2>Loading....</h2>
{:then post}
<input type="text" placeholder="Search..." bind:value={$filteredText} name="search"/>
<div class="post-container">
{#each $filteredPostStore as post}
<h3>{post.title}</h3>
<p>{post.body}</p>
{/each}
</div>
{:catch error}
<h3>Error while loading the data</h3>
{/await}
await
svelte syntax to make our life easier and then show the loading and error message.$filteredText
which is the store variable using bind:value
. So it automatically updates the store value. Wow!#each
syntax, we can iterate through the derived store $filteredPostStore
and display the post in a listWe will reach out when exciting new posts are available. We won’t send you spam. Unsubscribe at any time.