|
| 1 | +--- |
| 2 | +title: 'How to subscribe to changes of individual properties within a Svelte store' |
| 3 | +desc: "It's obvious once you see it. Not so obvious before that." |
| 4 | +img: /img/2022/ferenc-almasi-eYpcLDXHVb0-unsplash.jpg |
| 5 | +date: 2022-12-09 |
| 6 | +tags: |
| 7 | + - svelte |
| 8 | +--- |
| 9 | + |
| 10 | +Svelte stores are great. You can easily subscribe to them to be notified when a value changes, and react accordingly. |
| 11 | + |
| 12 | +```js |
| 13 | +//store.ts |
| 14 | +import { writable } from 'svelte/store'; |
| 15 | +import type { Filter } from './ListFilterTypes'; |
| 16 | + |
| 17 | +export const emptyFilter: Filter = { |
| 18 | + filterId: null, |
| 19 | + filterName: '', |
| 20 | + operator: null, |
| 21 | + not: false, |
| 22 | + value: '', |
| 23 | + min: '', |
| 24 | + max: '' |
| 25 | +}; |
| 26 | + |
| 27 | +export const filter = writable < Filter > Object.assign({}, emptyFilter); |
| 28 | +``` |
| 29 | + |
| 30 | +```js |
| 31 | +//App.svelte |
| 32 | +import { filter } from './store'; |
| 33 | + |
| 34 | +filter.subscribe(($filter) => { |
| 35 | + /* do awesome stuff */ |
| 36 | +}); |
| 37 | +``` |
| 38 | + |
| 39 | +But stores like the one above, which contain an entire object with various properties in it, always notify subscribers if _any_ property changes. What if you have a special case where you want a subscription that only executes when the `value` property is updated? |
| 40 | + |
| 41 | +I scratched my head on this for a few minutes. At first I thought there might be an extra argument to the `subscribe` method that I could make use of. A quick scan of the docs showed that there wasn't. So what's one to do? |
| 42 | + |
| 43 | +## Use a derived store |
| 44 | + |
| 45 | +Derived stores allow you to create a new store that is based on the value of an existing store. Any time the first store is updated the derived store gets updated. |
| 46 | + |
| 47 | +So we can easily add a derived store to our `store.ts` file: |
| 48 | + |
| 49 | +```js/0,4 |
| 50 | +import { writable, derived } from 'svelte/store'; |
| 51 | +
|
| 52 | +export const filter = writable < Filter > Object.assign({}, emptyFilter); |
| 53 | +
|
| 54 | +export const filterValue = derived(filter, ($filter) => $filter.value); |
| 55 | +``` |
| 56 | + |
| 57 | +Now there's a store named `filterValue` that will be updated only when `filter.value` changes. In all other ways we can treat it like a normal store, which means that subscribing to `filter.value` changes is super easy: |
| 58 | + |
| 59 | +```js |
| 60 | +//App.svelte |
| 61 | +import { filter, filterValue } from './store'; |
| 62 | + |
| 63 | +filterValue.subscribe(($filterValue) => { |
| 64 | + /* do awesome stuff that only needs to happen when filter.value changes */ |
| 65 | +}); |
| 66 | +``` |
0 commit comments