Reputation: 1516
In SvelteKit, I get "Subscribed" and "Unsubscribed" logged to the console each time I navigate between the /first and /second routes. I want to have the readable's start function run only once for each user who visits the website - allowing me to store fetched data that doesn't change often.
// stores.ts
import { readable } from 'svelte/store'
const { VITE_WEB_URL } = import.meta.env
export const message = readable('', set => {
console.log('Subscribed')
const fetchMessage = async () => {
const url = `${VITE_WEB_URL}/api/message`
const response: Response = await fetch(url)
return await response.text()
}
fetchMessage()
.then(set)
.catch(err => console.error('Failed to get message', err))
return () => {
console.log('Unsubscribed')
}
})
<!-- /routes/first.svelte -->
<script>
import { message } from '../stores'
</script>
<h1>First: {$message}</h1>
<a href="/second">Second</a>
<!-- /routes/second.svelte -->
<script>
import { message } from '../stores'
</script>
<h1>Second: {$message}</h1>
<a href="/first">First</a>
As I navigate between pages/routes in SvelteKit, unsubscribe is called so the next page/route invokes the start function as the "first" subscriber.
How can readable stores be shared across multiple pages/routes without re-running the start function? I've heard suggestions about using the template but have never seen an example.
Would the template get the store value and pass it as props to components or simply prevent the store from having a "last subscriber" (effectively keep the door open)?
Upvotes: 4
Views: 2860
Reputation: 1516
If you are using a template, the readable store can stay subscribed in a number of ways so as to not re-invoke the start function:
<!-- /lib/ComponentUsingMessage.svelte-->
<script>
import { message } from '../stores'
</script>
<p>{$message}</p>
<!-- /routes/__layout.svelte-->
<script>
import { message } from '../stores'
// Or include a component in the template that loads $message...
import ComponentUsingMessage from '$lib/ComponentUsingMessage.svelte'
</script>
<main>
Both subscribe but do not unsubscribe while template is loaded:
{$message}
<ComponentUsingMessage/>
<slot></slot>
</main>
Upvotes: 2
Reputation: 2627
It says that it is called when the first subscriber subscribes and then the delete function is called when the last subscriber unsubscribes. When you change routes it unsubscribes all subscribers and then runs the delete function, then when you get to the next route it reruns the initial function.
Upvotes: 1