0
votes

Svelte v3. I have a Shared.svelte component.

<script context="module">
    import {messages} from './store/store';

    export async function reloadData() {
        const url = 'https://domain.tld/api/v1/messages/';
        const response = await fetch(url);
        $messages = await response.json();
    }
</script>

And I'd like to use that reloadData() function in App.svelte.

<script>
// omitted
    import {reloadData} from "./Shared.svelte";

    onMount(async () => {
        await reloadData();
    })
</script>

I'm getting ReferenceError: reloadData is not defined

How can I have a shared library of functions that uses a store. If not for the store I could just write that in a .js file and export default. But export default leads to an error saying I can't export default in a Svelte component.

I have read module context / exports

1

1 Answers

1
votes

This line, inside <script context="module"> should not compile:

        $messages = await response.json();

For me, it throws:

Cannot reference store value inside <script context="module">

Which means you can't use the $ syntax in context="module", which makes sense since the $ prefix essentially means "automatically subscribe when the component is created, and unsubscribe when it is destroyed". But the module scope has no instance.

How can I have a shared library of functions that uses a store.

Taking that as the question... Like you were trying to do: either inside the context=module block of a component, or in a raw js file.

Svelte provides tool to work with store outside of component (instance) context. In fact, one of the main mission of stores is to bridge reactivity between "raw" js, and Svelte components context.

If you want to change the value of a writable store (like in your example), use the set method of the (writable) store:

messages.set(await response.json())

If you need to read the value of the store just once, use the get helper:

import { get } from 'svelte/store'

const messagesValue = get(messages)

If you need to track changes in the value, either subscribe to the store:

const dispose = messages.subscribe(messagesValue => {
  // do something with the value
  console.log(messagesValue)
})

// don't forget to call dispose when you're not interested in the value anymore!!

... or use derived stores, for the advantage of having your lifecycle (dispose) automatically managed by Svelte for you.

You should realize that a Svelte store is actually a very simple construct. It has a subscribe method, an optional set method and basically, that's all. Read the store contract in the docs: everything is in there. Three short rules. That means you can easily handle them (and create new sorts), because you know everything there is to know already!