How to get the content of a custom svelte store without calling update()?

339 Views Asked by At

I want to call a svelte custom store function without calling the update function. It feels ugly, especially since I don't want to update anything, I just want to query the store's content and returning a result.

To simplify, I've extended the svelte custom store tutorial (https://svelte.dev/tutorial/custom-stores) with a function that checks if the current number is equal to three:

App.js

<script>
    import { count } from './store.js';
</script>

<h1>The count is {$count}</h1>

<button on:click={count.increment}>+</button>
<button on:click={count.decrement}>-</button>
<button on:click={count.reset}>reset</button>
<button on:click={count.three}>is it 3? (inside)</button>

store.js

import { writable } from 'svelte/store';

function createCount() {
    const { subscribe, set, update } = writable(0);

    return {
        subscribe,
        increment: () => update(n => n + 1),
        decrement: () => update(n => n - 1),
        reset: () => set(0),
        three: () => update((n) => {
            console.log(n==3 ? 'yes' : 'no')
            return n
        })
    };
}

export const count = createCount();

Check the REPL: https://svelte.dev/repl/e124c879a48a4d51a53851576a3ea675?version=3.59.1

Is there a way to redefine the three function without using the update function?

1

There are 1 best solutions below

1
rixo On

Your example doesn't make it very clear what you really want the three function to do, but it seems you can achieve that with the get helper that gives you the current value of a store.

const count = writable(0);
const { subscribe, set, update } = count

const three = () => get(count) == 3 ? 'yes' : 'no'

Be mindful however, that it will subscribe and unsubscribe immediately to your store. This means that if your store has no subscribers when this happens, it's start/stop function will be called (firing a request each time, for exemple, if your store do that)...

In the end, it looks like what you really need is a derived store:

const three = derived(count, $count => $count == 3 ? 'yes' : 'no')

With a derived store, subscriptions to the different stores will naturally be managed optimally as a function of what you really use at a given time.