Trying to create tab based navigation in sveltekit which loads data from +page.server.js
based on what tab is selected. the active tab is selected from the url query ?mode=tabname
. Below is the snippet taken from a large project but I narrowed the issue down to this boilerplate code.
+page.svelte
<script>
import { page } from "$app/stores";
export let data;
$: mode = $page.url.searchParams.get("mode");
</script>
<section>
<nav>
<a href="?mode=list">list</a>
<a href="?mode=add">add</a>
</nav>
{#if mode == "list"}
<table>
<tr>
<th>id</th>
<th>name</th>
</tr>
{#each data.list as l (l.id)}
<tr>
<td>{l.id}</td>
<td>{l.name}</td>
</tr>
{/each}
</table>
{:else if mode == "add"}
<form action="">
<input type="text" name="name" />
<button type="submit">save</button>
</form>
{:else}
<b>Select an option from above</b>
{/if}
</section>
+page.server.js
export const load = async ({ url }) => {
// maybe needed in both tabs.
const info = {
appname: "demo",
};
// only needed in "list" tab.
const list = [
{ id: 1, name: "test one" },
{ id: 2, name: "test two" },
{ id: 3, name: "test three" },
];
// Previously, I was returning all the data
// without detecting any tab.
// There was no problem with it apart from
// performance issues
// return {
// info,
// list,
// };
// seperating the returned data based on tab name
// that's when the issue arise
const mode = url.searchParams.get("mode");
if (mode == "list") {
return {
info,
list,
};
} else if (mode == "add") {
return {
info,
};
}};
After navigation from 'list' to 'add' tab, this error is thrown in chrome console:
chunk-ERBBMTET.js?v=7f9a88c7:2609 Uncaught (in promise) Error: {#each} only works with iterable values.
at ensure_array_like_dev (chunk-ERBBMTET.js?v=7f9a88c7:2609:11)
at Object.update [as p] (+page.svelte:18:29)
at Object.update [as p] (+page.svelte:12:35)
at update (chunk-ERBBMTET.js?v=7f9a88c7:1351:32)
at flush (chunk-ERBBMTET.js?v=7f9a88c7:1317:9)
Looks like it's complaining about data.list
even after navigation to the tab which does not even need data.list
. returning both info
and list
object for every tab solves the issue and also wrapping the #each
block in #if
block does the trick eg:
{#if data.list}
{#each data.list as l (l.id)}
<tr>
<td>{l.id}</td>
<td>{l.name}</td>
</tr>
{/each}
{/if}
Given that I'm not very experienced in SvelteKit, I not sure what am I doing wrong. Any help is appriciated. Thanks
Top comments (0)