javascriptsveltesveltekit

fetch asynchronous data svelte


basic background

I am designing an anonymous board using Svelte 4, now I have a route routes\board\[board_url]\ which has +page.server.js and +page.svelte. In +page.server.js, I will get information like board_name and board_intro from database, like this:

// +page.server.js
export const load = async ({ params }) => {
  // code for get some info from `board` table
  return {
    board_name, // like 'notopic',
    board_intro, // like  'Emmmmmm',
    board_url, // like 'notopic'
  }
}

and in the +page.svelte, I use the board_url in the data of +page.server.js return, to fetch API /board/getPost/[board_url] to get those posts in this board, all seem to be well, like this:

// +page.svelte
<script>
import { onMount } from 'svelte';

onMount(() => {
  const board_url = window.location.href.split('/').at(-1);
  fetch(`/board/getPosts/${board_url}`).then(r => r.json())
  // other data handle
})
</script>
<!-- code for 20 posts in the board -->

problem

the problem is when I use <a> tag to go to other board, like from /board/buybuybuy to /board/notopic, It won't trigger onMount() function, cause I know the component has already mounted.

two questions

  1. how to trigger once the fetch request every time after I change the route(refresh or use <a>, use store? or other way
  2. cause we can fetch first 20 posts from API, and when the page scroll to the bottom, we can use IntersectionObserver to trigger another fetch to next page, if you can offer answer of question 1, please also give some advise to trigger the get for next page post

possible way

There is a solution, add data-sveltekit-reload to <a> tag cause a refresh of page, but I think it seems not so svelte like the framework name.


Solution

  • If you want to trigger your functoin on navigation try using the onNavigate lifecycle instead of onMount

    // +page.svelte
    <script>
    import { onNavigate} from '$app/navigation';
    
    onNavigate(() => {
      const board_url = window.location.href.split('/').at(-1);
      fetch(`/board/getPosts/${board_url}`).then(r => r.json())
      // other data handle
    })
    </script>
    <!-- code for 20 posts in the board -->
    

    If onNavigate doesn't work properly you may try manually updating your board_url using the load function like this

    //+page.js - not .server.js since it must run on the client
    export const load = ({ url }) => {
        const { url } = url;
    
        return {url};
    };
    
    // +page.svelte
    <script>
        export let data
        $: ({url} = data) 
       
       $: if (url) {
         const board_url = window.location.href.split('/').at(-1);
         fetch(`/board/getPosts/${board_url}`).then(r => r.json())
         // other data handle
       }
    </script>
    <!-- code for 20 posts in the board -->