I have a Svelte & Sapper app where I am using a Svelte writable store to set up a variable with an initial blank string value:
import { writable } from 'svelte/store';
export let dbLeaveYear = writable('');
In my Index.svelte
file I am importing this and then working out the value of this variable and setting it (I am doing this within the onMount
function of ```Index.svelte if this is relevant):
<script>
import {dbLeaveYear} from "../stores/store.js"
function getCurrentLeaveYear() {
const today = new Date();
const currYear = today.getFullYear();
const twoDigitYear = currYear.toString().slice(-2);
const cutoffDate = `${twoDigitYear}-04-01`
const result = compareAsc(today, new Date(cutoffDate));
if (result === -1) {
$dbLeaveYear = `${parseInt(twoDigitYear, 10) - 1}${twoDigitYear}`;
} else {
$dbLeaveYear = `${twoDigitYear}${parseInt(twoDigitYear, 10) + 1}`;
}
}
onMount(() => {
getCurrentLeaveYear();
});
</script>
I have a child component being rendered in the Index.svelte
<Calendar />
Inside the Calendar child component I am importing the variable and trying to access it to perform a transform on it but I am getting errors that it is still blank - it is seemingly not picking up the assignment from Index.svelte
:
<script>
import {dbLeaveYear} from "../stores/store.js"
const calStart = $dbLeaveYear.slice(0, 2)
</script>
However if I use the value in an HTML element in the same Calendar child component with <p>{$dbLeaveYear}</p>
it is populated with the value from the calculation in Index.svelte
.
How can I access the store variable inside the <script>
tag of the child component? Is this even possible? I've tried assiging in onMount
, I've tried assigning in a function - nothing seems to work and it always says that $dbLeaveYear
is a blank string.
I need the value to be dynamic as the leave year value can change.
The answer here is a combination of Sapper preload and the ability to export a function from a store.
in store.js
export the writable store for the variable you want and also a function that will work out the value and set the writable store:
export let dbLeaveYear = writable('');
export function getCurrentLeaveYear() {
const today = new Date();
const currYear = today.getFullYear();
const twoDigitYear = currYear.toString().slice(-2);
const cutoffDate = `${twoDigitYear}-04-01`
const result = compareAsc(today, new Date(cutoffDate));
if (result === -1) {
dbLeaveYear.set(`${parseInt(twoDigitYear, 10) - 1}${twoDigitYear}`);
} else {
dbLeaveYear.set(`${twoDigitYear}${parseInt(twoDigitYear, 10) + 1}`);
}
}
In the top-level .svelte
file, use Sapper's preload()
function inside a "module"
script tag to call the function that will work out the value and set the writable store:
<script context="module">
import {getCurrentLeaveYear} from '../stores/store'
export async function preload() {
getCurrentLeaveYear();
}
</script>
And then in the component .svelte
file, you can import the store variable and because it has been preloaded it will be available in the <script>
tag:
<script>
import {dbLeaveYear} from '../stores/store'
$: startDate = `20${$dbLeaveYear.slice(0, 2)}`
$: endDate = `20${$dbLeaveYear.slice(-2)}`
</script>