Svelte/Sapper Issue with Switching Components
I ran into what might be my first Svelte bug when working on the Big2 card game project. Very roughly, I have a page setup that looks like this (<script>
and <style>
sections omitted, and unrelated component properties omitted):
<main>
{#if $state === 'game'}
<GameStageLocal />
{:else if $state === 'deal'}
<DealAnimation onDone={dealingDone} />
{:else}
<div>Initializing...</div>
{/if}
</main>
The <DealAnimation>
component plays some game start animation and when it's done, it calls the onDone
handler passed into it. What it will do is to update state
(a Writable Store) to game
so the interactive game UI will start.
As you can deduce from the code above, $state
is an auto-subscribed store so when its value changes, it would change the DOM on the page such that <GameStageLocal>
is now what's on the page, and <DealAnimation>
would be removed from the DOM.
When testing it, the Firefox console gave the following error:
TypeError: t.parentNode is null
It was a bit baffling since I couldn't really find an error in my Svelte code and there wasn't any error in the Svelte dev build output. Upon searching online, I came across this StackOverflow post which has exactly my issue. Although the answer mentions that:
Ran into this error recently. In my case it was due to another library changing the DOM. (In my case fontawesome)
I was not using another library to change the DOM; only Svelte. Either way, though, the described fix in the answer worked for me, which was to wrap my components inside those conditions in another node, like below:
<main>
{#if $state === 'game'}
<div>
<GameStageLocal />
</div>
{:else if $state === 'deal'}
<div>
<DealAnimation onDone={dealingDone} />
</div>
{:else}
<div>Initializing...</div>
{/if}
</main>
And this worked fine.
Parting Thoughts
I think this does go to show the relative immaturity of Svelte in general, compared to React or Vue. I remain a fan of Svelte, but nevertheless it's good to keep in mind that when you use a small framework, you're bound to run into actual bugs in the framework.