DEV Community

TJ Fogarty
TJ Fogarty

Posted on • Originally published at tj.ie

8 4

Derived Stores with Svelte

This was originally posted on my site.

Svelte has been getting a lot of attention recently, and rightly so. If you've used the likes of Vue or React in the past then Svelte won't be a million miles away. I recommend following their interactive tutorial if you're interested.

Coming from a Vue background, one feature I love is computed properties. If you want to store some sort of value that depends on the reactive state, but you don't want to manually update it when state changes, this is where they come in. For example, a greeting property could return something like "Hello, ${this.name}!". Vue knows to update greeting whenever name changes.

Svelte offers a similar solution in what it calls derived stores. To show how this works, I created a small app that takes a JSON feed and lets us filter it. The feed contains a list of jobs, and I want to be able to search by job title, and only show remote jobs via a checkbox.

The initial stores would be as follows:

import { writable } from 'svelte/store'

export const jobs = writable([])
export const searchTerm = writable('')
export const remoteOnly = writable(false)
Enter fullscreen mode Exit fullscreen mode

At some stage, when the app is ready, the jobs store is populated with an array of jobs from the feed. When I type in the search input the searchTerm store is updated, and when I toggle the remote-only checkbox, the remoteOnly store is toggled.

Ideally what I'd like to do is avoid editing the jobs store. I'd like to keep the original list untouched so I can return to the original state.

This is where I can use derived stores. First I need to import it by updating the top-level import statement:

import { writable, derived } from 'svelte/store'
Enter fullscreen mode Exit fullscreen mode

Now I can declare my derived store.

export const filteredJobs = derived(
  [jobs, remoteOnly, searchTerm],
  ([$jobs, $remoteOnly, $searchTerm]) => {
    return $jobs
  }
)
Enter fullscreen mode Exit fullscreen mode

The first argument is the store or stores, I wish to derive from. You only need to pass an array if you wish to use more than one. The second argument here is the callback, which gets passed the stores we asked for. At the moment we're returning the original jobs store untouched. Let's create a function to show only the remote jobs:

function filterByRemote(jobs, remoteOnly) {
  if (!remoteOnly) return jobs

  return jobs.filter(job => !job.location)
}

export const filteredJobs = derived(
  [jobs, remoteOnly, searchTerm],
  ([$jobs, $remoteOnly, $searchTerm]) => {
    return filterByRemote($jobs, $remoteOnly)
  }
)
Enter fullscreen mode Exit fullscreen mode

A remote job here is any job that doesn't have a location set. If remoteOnly is set to false we'll return the jobs array early.

A similar approach is taken for the search term. It's not the most robust of searches, but it does the job:

function filterByRemote(jobs, remoteOnly) {
  if (!remoteOnly) return jobs

  return jobs.filter(job => !job.location)
}

function filterBySearchTerm(jobs, searchTerm) {
  if (!searchTerm) return jobs

  return jobs.filter(job => {
    const title = job.title.toLowerCase().replace('-', ' ')
    const formattedTerm = searchTerm.toLowerCase().trim()

    return title.includes(formattedTerm)
  })
}

export const filteredJobs = derived(
  [jobs, remoteOnly, searchTerm],
  ([$jobs, $remoteOnly, $searchTerm]) => {
    return filterBySearchTerm(filterByRemote($jobs, $remoteOnly), $searchTerm)
  }
)
Enter fullscreen mode Exit fullscreen mode

If we work from the inside-out, we'll see filterByRemote returns an array of jobs, which then becomes the first argument in the call to filterBySearchTerm.

That's my first experience with Svelte. Hopefully not the last as it's a refreshing take on what I've been doing previously.

See the demo
View the source

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay