javascript - Render Markup while waiting for data from load-function in svelte - Stack Overflow

I know there are some discussions about that. For example here:However, I still do not understand it pl

I know there are some discussions about that. For example here:

However, I still do not understand it pletely. I have a +page.svelte and a corresponding +page.js file. In the +page.js file I fetch some external data. This might take a second. While doing so I want to at least let the user know that the data is beinf fetched or something. Or even render the markup the does not depend on the data itself.

The code in the +page.js looks something like this:

import { fetchAllData } '$lib/utils';

export async function load({ fetch, url }) {
    let id = url.searchParams.get('id');
    let data = fetchAllData(id, fetch);
    return { data };
}

I wonder if/how I could do something like this in the +page.svelte

<script>
    export let data;
</script>

{#await data}
    waiting
{:then d}
    respo
{/await}

I know there are some discussions about that. For example here:

https://github./sveltejs/kit/discussions/8640

However, I still do not understand it pletely. I have a +page.svelte and a corresponding +page.js file. In the +page.js file I fetch some external data. This might take a second. While doing so I want to at least let the user know that the data is beinf fetched or something. Or even render the markup the does not depend on the data itself.

The code in the +page.js looks something like this:

import { fetchAllData } '$lib/utils';

export async function load({ fetch, url }) {
    let id = url.searchParams.get('id');
    let data = fetchAllData(id, fetch);
    return { data };
}

I wonder if/how I could do something like this in the +page.svelte

<script>
    export let data;
</script>

{#await data}
    waiting
{:then d}
    respo
{/await}
Share Improve this question asked Jun 11, 2023 at 8:31 LennLenn 1,4991 gold badge12 silver badges28 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

Although H.B.'s answer is technically correct, I don't think +page.js is the right tool for your use case.

The whole point of having a +page.js instead of fetching inside an onMount callback is to avoid the "loading" problem.

Let me explain, +page.js is executed:

  1. on server side for initial route, e.g. enter url in address bar, or hit browser refresh button.
  2. on client side for subsequential in-site navigation, e.g. click a link on page A to navigate to page B, then +page.js for B is executed on client (both page A and B need to be routes within the same SvelteKit project)

For 1st case, the data loading is processed on server, page won't even render before the data is loaded. So user will have to wait a bit while staring at a blank screen. If this takes long they might feel your website is slow.

For 2nd case, the data loading is actually handled in page A, instead of page B. It'll be like, user click a link on page A, but navigation to page B won't happen until +page.js finishes executing. So if it takes long, users stay on page A, and might think they missed clicking the link some how, and probably would click it again.

Knowing this behavior should help you decide if +page.js is the right tool to your problem.

My suggestion is,

  • For normal use case that takes reasonable amount of time to load data, use +page.js and you shouldn't have to worry about loading state.
  • For special use case where it takes insanely long to load data, then you shouldn't even use +page.js. You should just use the good old onMount(() => fetch(...)) and show a loading inidicator to keep your user patient.

+page.js is designed specifically for "normal use case", don't wrestle with the tool, just choose the right one.

Edit: In v2, top level promises are not awaited automatically.

Top level promises in the data are automatically awaited before rendering the page, you would have to assign the promise to a deeper property, e.g.

return { deferred: { data: fetchAllData(id, fetch) } }
{#await data.deferred.data}

Docs

(Would remend renaming things, data is not very descriptive and the page data variable is already called data as well.)

You've pretty much answered your own question, this is a snippet from their official docs(link below) so this works perfectly.

<script>
    let promise = getRandomNumber();

    async function getRandomNumber() {
        const res = await fetch(`/tutorial/random-number`);
        const text = await res.text();

        if (res.ok) {
            return text;
        } else {
            throw new Error(text);
        }
    }

    function handleClick() {
        promise = getRandomNumber();
    }
</script>

<button on:click={handleClick}>
    generate random number
</button>

{#await promise}
    <p>...waiting</p>
{:then number}
    <p>The number is {number}</p>
{:catch error}
    <p style="color: red">{error.message}</p>
{/await}

https://svelte.dev/examples/await-blocks

Here is a example. I based it off your code :-

https://svelte.dev/repl/e81ca49d739b4f86a2753aed59443467?version=3.59.1

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745334492a4623039.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信