Svelte: Fetch async data (Logic / await blocks)
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>