skip to Main Content

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

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

However, I still do not understand it completely. 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}

3

Answers


  1. 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 recommend renaming things, data is not very descriptive and the page data variable is already called data as well.)

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
  3. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search