How to use custom store methods in svelte?
Asked Answered
P

1

6

I'm making a modal, with its attributes stored in a store. Rather than open it like this, from an element: on:click={() => $modal.isOpen = true}

I want to open it like this: on:click={() => $modal.toggle()} from an element.

Here is my code:

export const modal = writable({
    isOpen: false,
    title: 'Title',
    content: 'Content',
    toggle: () => {
        console.log(modal)
        modal.set({ ...modal, isOpen: true });
    }
}); 

When I log modal, it logs just the set, subscribe, update methods. Then when I click again, those methods are gone: it properly overwrites them, it just seems that I can never get the modal's initialized state. I've tried to access the current object with this or parameters ((a, b) =>) but neither return anything.

Posture answered 29/10, 2019 at 15:46 Comment(0)
B
14

The argument passed to writable only contains data, not methods. To create a custom store, do it like this tutorial — create your own store factory that wraps writable:

const toggleable = initial => {
  const store = writable(initial);

  return {
    ...store,
    toggle: () => store.update(n => !n)
  };
};

const modal = toggleable(false);

Demo here: https://svelte.dev/repl/682ef8309f924ba7ad8de1e2f5069988?version=3.12.1

Bonanza answered 29/10, 2019 at 16:56 Comment(2)
Thanks, Rich! I feel like I'm close but I just cannot seem to import this update method properly. Shown here: svelte.dev/repl/a5457b36d46d48d4bb271852cf6d0c75?version=3 I've tried all manner of things between the two examples shown (and more) but it seems if I ever get update() working, then something else breaks.Posture
store.update takes a function, not a value. The function receives the old value and returns a new one. So it should be store.update(old => ({ ...old, isOpen: !old.isOpen }))Bonanza

© 2022 - 2024 — McMap. All rights reserved.