Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SvelteKit - load() not called from component but works as a Page

If the file test.svelte below is a Page in /routes, it successfully calls load() and populates the template with the JSON array it retrieves when I access it via http://localhost:3000/test. If I move this file to /lib and import it as a component in /routes/index.svelte, the load() method of the component never runs when I go to http://localhost:3000.

test.svelte

<script context="module" lang="ts">
  /**
     * @type {import('@sveltejs/kit').Load}
   */
  export async function load({ fetch }) {
    const url = '/api/announcement'
    const res: Response = await fetch(url)

    if (res.ok) {
      const sections: Announcement[] = await res.json()
      return {
        props: {
          sections
        }
      }
    }

    return {
      status: res.status,
      error: new Error(`Could not load ${url}`)
     }
  }
</script>

<script lang="ts">
  export let sections: Announcement[] = []
</script>

<template>
  {#each sections as section}
    <p>
      {section.title}<br/>
      {section.description}
    </p>
  {/each}
</template>

Here is routes/index.svelte that tries to load it as a component from /lib:

<script context="module" lang="ts">
  import Test from '$lib/test.svelte'
</script>

<template lang="pug">
  .container
    Test
</template>

Seems like I'm doing something obviously wrong but I'm new to Svelte and SvelteKit. While I considered retrieving the data in routes/index.svelte and pass it down to the component, I was hoping to encapsulate the data retrieval in the component to keep it simpler.

like image 222
nstuyvesant Avatar asked May 06 '21 16:05

nstuyvesant


1 Answers

The docs state (emphasis mine)

A component that defines a page or a layout can export a load function that runs before the component is created.

This means you cannot use the load function in a regular component.

You can however still use onMount, to load data when the component is mounted.

Alternatively, you keep the load function in your page and pass the retrieved values to the component itself.

If you really do not want a large load function in your page, you can also put it in a third file (loader.js) and import it from there in the page (in the end the load function has to be in the page)

<script context="module">
  import _load from './loader.js';
  export const load = _load;
</script>
like image 191
Stephane Vanraes Avatar answered Oct 06 '22 06:10

Stephane Vanraes