I have a svelte store that has the following code
import { writable } from "svelte/store";
import { onMount, onDestroy } from "svelte";
export const modalStore = () => {
const { subscribe, update } = writable({
showModal: false,
});
onMount(() => {
window.addEventListener("keydown", handleKeyDown);
});
onDestroy(() => {
window.removeEventListener("keydown", handleKeyDown);
});
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") {
update(stateObj => ({...stateObj, showModal: false}));
}
}
return {
subscribe,
openModal: () => update(stateObj => ({ ...stateObj, modal: true })),
closeModal: () => update(stateObj => ({ ...stateObj, modal: false })),
handleKeyDown,
}
}
Edit
I have accessed the store by the following code
let modalState = modalStore();
Then checked the state by $modalState and the accessed the function by modalStore.openModal();
It throws 500 error with - window is not defined
How can I solve it?
I have a svelte store that has the following code
import { writable } from "svelte/store";
import { onMount, onDestroy } from "svelte";
export const modalStore = () => {
const { subscribe, update } = writable({
showModal: false,
});
onMount(() => {
window.addEventListener("keydown", handleKeyDown);
});
onDestroy(() => {
window.removeEventListener("keydown", handleKeyDown);
});
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") {
update(stateObj => ({...stateObj, showModal: false}));
}
}
return {
subscribe,
openModal: () => update(stateObj => ({ ...stateObj, modal: true })),
closeModal: () => update(stateObj => ({ ...stateObj, modal: false })),
handleKeyDown,
}
}
Edit
I have accessed the store by the following code
let modalState = modalStore();
Then checked the state by $modalState and the accessed the function by modalStore.openModal();
It throws 500 error with - window is not defined
How can I solve it?
Share edited Oct 26, 2022 at 11:04 jeff asked Oct 26, 2022 at 9:21 jeffjeff 1,0202 gold badges10 silver badges31 bronze badges 6-
2
The problem has to be SSR. When using svelteKit, every ponent gets rendered on the server before being sent to the browser. The thing is,
window
is used inside ofonMount
so I think that shouldn't be the problem. Can you share maybe how you are using the store? – Odilf Commented Oct 26, 2022 at 10:19 -
modalStore
is exported, check whetheropenModal
is being called anywhere outside of anonMount
function? – Oscar Hermoso Commented Oct 26, 2022 at 10:20 - @OscarHermoso: I used the openModal function in the ponent in which the store (modalStore) was called. I have initiated the store by let modalState = modalStore(); and then accessed modalState.openModal – jeff Commented Oct 26, 2022 at 11:00
- 1 Just as you can add event listeners to any DOM element, you can add event listeners to the window object with <svelte:window>. Example: <svelte:window on:keydown={handleKeydown}/> – voscausa Commented Oct 26, 2022 at 12:17
- 1 @OscarHermoso Actually I was able to get it working my slightly modifying the onMount function (posted here ) – jeff Commented Oct 26, 2022 at 13:32
2 Answers
Reset to default 7The problem is that onDestroy
gets executed on the server. So instead of using onDestroy
the function returned from onMount
should be used.
Docs:
Out of
onMount
,beforeUpdate
,afterUpdate
andonDestroy
, this is the only one that runs inside a server-side ponent.
export const modalStore = () => {
const { subscribe, update } = writable({
showModal: false,
});
onMount(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") {
update((storeObj) => {
storeObj.showModal = false;
return storeObj;
});
}
};
window.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
});
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "Escape") {
update(stateObj => ({...stateObj, showModal: false}));
}
}
return {
subscribe,
openModal: () => update(stateObj => ({ ...stateObj, showModal: true })),
closeModal: () => update(stateObj => ({ ...stateObj, showModal: false })),
handleKeyDown,
}
}
I dont know how. But its working now without error