SvelteKit page data doesn't always update when opening new page in the same dynamic route
Asked Answered
A

4

12

I have a route structure /items/[category]. When the user is browsing /items/category1 and then tries to go to a another page in the same route (eg. /items/category2) the page data usually updates to show category2 items, but not always. Sometimes the URL updates in the browser but the page data still shows items from the previous URL.

My +page.server.js for /items/[category] looks like:

import { getItems } from '$lib/services/ItemService';
export const csr = false;
export const load = ({ locals, params }) => {
    return {
        items: getItems(locals, `category = "${params.itemCategory}"`)
    };
};

And my +page.svelte is:

<script>
   import { ItemCard } from '$lib/components';
   export let data
   let items = data.items
</script>
...
<div class="grid grid-cols-1 md:grid-cols-3 px-4 gap-6">   
   {#each items as item}
      <ItemCard {item}/>
   {/each}
</div>

The getItems() function retrieves JSON data from pocketbase and is working correctly.

I read that adding the export const csr = false; to the +page.server.js should solve the problem, but it appears that the page still isn't always re-loading data from the server when swapping between routes.

Anastigmat answered 23/11, 2022 at 16:5 Comment(0)
B
25

You change local state non-reactively:

let items = data.items

If data is updated by the router, items will not.

Making it reactive might fix the issue:

$: items = data.items

You can also destructure props reactively, which requires additional parentheses:

$: ({ items } = data)

SvelteKit docs on this issue.

Byran answered 23/11, 2022 at 16:12 Comment(0)
A
3

Change

let categoryUrl = $page.params.category;

to

$: categoryUrl = $page.params.category;
Atthia answered 20/10, 2023 at 13:53 Comment(0)
E
0

The 'params' attribute is not reactive if you navigate from a similar route (e.g. /items/category2 -> /items/category3). What worked for me for a similar issue was:

import { navigating } from '$app/stores';
let categoryUrl = $page.params.category;
$: {
    categoryUrl = typeof window !== 'undefined' ?  window.location.href.split('/').pop() : $page.params.category;
}
$: if($navigating) {
    let newUrl = typeof window !== 'undefined' ?  window.location.href.split('/').pop() : $page.params.category;
    if(categoryUrl !== newUrl) { 
        .....
    }
}
Edouard answered 31/1, 2023 at 7:16 Comment(1)
params is reactive, or rather, the store that it is in is. If you just write {$page.params.category} somewhere in the template, it should update just fine. Maybe you navigated without using goto or had some intermediary variable that was not declared reactively.Byran
L
-1

This problem has been bugging me for days, and I finally found that the easiest solution is to use window.location.href.

Write your code like this:

<button on:click={() => {
        window.location.href = `/path/${id}`;
      }}>
Go
</button>
Launalaunce answered 9/1, 2023 at 16:49 Comment(1)
This will cause a page reload, which is wasteful. SvelteKit has a client-side router that only loads data that is not already loaded. Your page is probably mutating state non-reactively.Byran

© 2022 - 2024 — McMap. All rights reserved.