Rüzgar
Rüzgar

Reputation: 997

How to send extra parameters from page.svelte to page.js inside the same route in Sveltekit

I am trying to understand how sveltekit works. Inside my sveltekit demo app, I have +page.svelte and +page.js files at the same route.

+page.js, which gets data from the API, sends data to +page.svelte. But it is a one way communication. What if I want to send some parameters to +page.js; sth like how many items that I want to show on my page.

I see that params only contains slug. And I don't want to use url queries like /products?limit=10&skip=0

page.js

import { Store } from '@models'

/** @type {import('./$types').PageServerLoad} */
export async function load({params}) {
    // Sth like this:
    let limit = params.limit || 10
    let skip = params.skip || 0
    let res = await Store.get(limit,skip)
    return {
        store: res
    };
};

page.svelte

export let data
let products = data.store

const loadMore = () => {
    // What to do next???
}
{#each products as product}
    {product.title}
{/each}
<button on:click={loadMore}>Load More</button>

Is there a way to achieve this? Or am I missing something?

Upvotes: 1

Views: 1541

Answers (2)

R&#252;zgar
R&#252;zgar

Reputation: 997

I found a new way of achieving what I really wanted. It still does not seem to be the best solution, but it is the most efficient way for my case right now.

I used the built-in depends() function with invaidate as described here. This way I can update the data object for my needs.

So the final code is like below

page.svelte

    const loadMore = () => {
        data.loadMore(2)
    }
    const reset = () => {
        data.reset()
    }

page.js

import { Store } from '@models'
import { invalidate } from '$app/navigation';
let count = 1
/** @type {import('./$types').PageServerLoad} */

export async function load({depends}) {
    let res = await Store.get(count)
    depends('update');
    return {
        store: res,
        count: count,
        loadMore: (e) => {
            invalidate('update');
            count+= e
        },
        reset: () => {
            invalidate('update');
            count = 1
        }
    };
}

Important

I did not have much time to test this. So please read the documentation carefully before using. I would appreciate any comments for this approach.

Upvotes: 1

brunnerh
brunnerh

Reputation: 185280

See the advanced routing documentation.

If you do not want to use a query the only alternative is using optional parameters, so you probably should move your route files to something like:

src/routes/products/[[skip]]/[[limit]]/+page.svelte

This will allow the route to have those two parameters at the end, but they are not required. So all of these routes are valid:

/products
/products/1
/products/1/10

Parameters that are not provided will not appear in the params object. All param values are strings.

Load more items would just be a matter of navigating using goto, e.g.

import { goto } from '$app/navigation';
import { page } from '$app/stores';

$: skip = +($page.params.skip ?? 0);
$: limit = +($page.params.limit ?? 10);

const loadMore = () => {
    goto(`/products/${skip + limit}/${limit}`);
}

Upvotes: 2

Related Questions