Eliaslog.pw

This is how async fetching of data in Svelte works.

In this example, we’re starting with a basic Svelte component, that features a function fetchData that gets saved to the variable data.

<!-- Component.svelte -->

<script>
  const fetchData = () => {}

  let data = fetchData()
</script>

<div class="posts"></div>

<style></style>

The function is going to do the fetching and awaiting, while the svelte component will later observe the data variable. When the data fetching has finished, the data will be rendered.

Building the fetch function

Our fetchData function looks like this:

/*Component.svelte*/

<script>
  const fetchData = () => {
    return fetch("https://eliaslog.pw/api/posts.json")
      .then(res => res.json())
      .then(res => res)
      .catch(e => console.error(e))
  }

  let data = fetchData()
</script>

<div class="posts"></div>

<style></style>

We are using the JS-fetch function/API to query a given data resource.

In this instance, we’re fetching a json file that contains data about the latest two posts of this blog. After converting it to JSON, we return the received data.

Our component should now have saved the data to the data variable.

Rendering the data in component

It is key that our component waits with the rendering until the data is ready.

For this, svelte provides the #await and :then blocks:

<!-- Component.svelte -->

<script>
  const fetchData = () => {
    return fetch("https://eliaslog.pw/api/posts.json")
      .then(res => res.json())
      .then(res => res)
      .catch(e => console.error(e))
  }

  let data = fetchData()
</script>

<div class="posts">
  {#await data}
  <span>Loading data...</span>
  {:then data}
  <!-- Render data -->
  <h1>Most recent Posts:</h1>

  {/await}
</div>

<style></style>

The keyword #await takes in a variable, in this case data, which it observes.

During the time where the given variable is a false value, the markup before :then is rendered (”Loading data…”).

After the data has been filled in, the part after the false is displayed.

Final code

To get to our working component and thus final code, we’re using the svelte {#each} block to render the linked title to the post.

<!-- Component.svelte -->

<script>
  const fetchData = () => {
    return fetch("https://eliaslog.pw/api/posts.json")
      .then(res => res.json())
      .then(res => res)
      .catch(e => console.error(e))
  }

  let data = fetchData()
</script>

<div class="posts">
  {#await data}
  <span>Loading data...</span>
  {:then data}
  <!-- Render data -->
  <h1>Most recent Posts:</h1>

  {#each data as data (data.slug)}
  <a href="https://eliaslog.pw/{data.slug}">
    <h2>{data.title}</h2>
  </a>
  {/each} {/await}
</div>

<style></style>

CodeSandbox for this code

The creation of this post was made possible by coffee.
Buy me a coffee