I have a page with multiple components, like tables and displayed in one page.
My +page.svelte:
<script>
.
.
<script>
<div class="page-content">
<Row>
<Table1 />
<List /> -->
<Table2 />
</Row>
</div>
My REST API call as an example in one of my component:
<script>
let todos // 'forever' undefined
async function fetchTodos() {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/')
return await response.json()
}
</script>
{#await fetchTodos() then todos}
<h1>{todos.length} todos!</h1>
{/await}
However if I want to use it inside each tables and some of the data in the List component, according to this solution I need to place the same call all of my component and I generate unnecessary extra same calls.
For sharing state I would recommend using a context (setContext
/getContext
), these are available in an entire component sub-tree. E.g. use it in a layout that all relevant pages use.
To make the context reactive, you can use a store.
For polling you can just use setInterval
but that should be cleaned up once the data is no longer required; stores can have a StartStopNotifier
to start polling on first subscription and stop on last unsubscribe.
Note that you can also load data directly in a layout which then could be used to initialize the store.
Basic example without initial data:
// lib/data-store.js
import { writable } from 'svelte/store';
import { browser } from '$app/environment';
// ...
export function createDataStore() {
const store = writable(null, (set, update) => {
if (browser == false)
return;
async function getData() {
const newData = await fetchNewData();
set(newData); // or use update to e.g. append to existing data
}
const handle = setInterval(getData, 5000);
getData();
return () => clearInterval(handle);
});
return store;
}
<!-- +layout.svelte -->
<script>
import { createDataStore } from '$lib/data-store';
import { setContext } from 'svelte';
setContext('data', createDataStore());
</script>
<slot />
<!-- some component in sub-tree -->
<script>
import { getContext } from 'svelte';
const store = getContext('data');
</script>
{$store}
(To keep polling independent of subscribers you can use onMount
to start and its returned function to stop. E.g. if you need a consistent stream of data.)