Suspense in Svelte: Writing Components That Don’t Care

Loading data, managing async requests, and communicating status information back to the end user takes an impressive portion of our time writing web applications. What would it look like if we could write components that did not care about any part of…


This content originally appeared on DEV Community and was authored by Brian K

Loading data, managing async requests, and communicating status information back to the end user takes an impressive portion of our time writing web applications. What would it look like if we could write components that did not care about any part of that?

Our Component

Let's write a simple component that displays all the possible evolutions of a Pokemon using the data supplied from pokeapi.com.

<script>
// file: Evolution.svelte
import Link from './link.svelte'
import { getEvolution, getPokemon } from '$lib/data.js'

export let id
$: pokemon = getPokemon(id)
$: evolution = getEvolution($pokemon?.evolution_chain, $pokemon?.id)
</script>

{#if $evolution?.length}
  {#each $evolution as id}
    <Link { id } />
  {/each}
{:else}
  <p>This Pokemon doesn't evolve!</p>
{/if}

We've accomplished our goal! This component is really simple and straightforward but also does not care about loading states, error handling, or data fetching. Unfortunately, something has to worry about those aspects in a production application. What can we do to allow us to write components this simple without compromising?

Data Fetching

As part of the "do not care" mantra, we want to avoid knowing if any other component needs the same data. Let's just make the request and let our data layer worry about caching and pooling requests between various components.

An implementation of our getPokemon function might look like this:

// File: $lib/data.js
import { swr } from '@svelte-drama/swr'
import { suspend } from '@svelte-drama/swr/plugin'

export function getPokemon (id: number) {
  const url = `https://pokeapi.co/api/v2/pokemon-species/${ id }/`
  const { data } = swr(url, {
    plugins: [suspend()]
  })
  return data
}

@svelte-drama/swr will cache every request keyed on the url passed to it. If multiple components request the same key at the same time, only one request will be made and all the components will be updated when it returns. If this request has been made before, we can even skip making the request at all and just return the cached data.

Using the suspend plugin here notifies our application that we need certain data and this component isn't ready to render until we have finished fetching that data. Exactly what that means is in the next section.

Finally, data returned here is a Svelte store. It will start off as undefined while fetching data, which our component unfortunately does need to be aware of, and will update to our data once the request is finished.

Suspense

To fit the final piece of the puzzle, we still need to show loading indicators to the user. Let's take our <Evolution> component and wrap it in a page that looks like this:

<script>
// index.svelte
import { Suspense } from '@svelte-drama/suspense'
import Evolution from './Evolution.svelte'
</script>

<h1>Eevee Evolutions</h1>
<Suspense>
  <Evolution id={ 133 } />
  <p slot="loading">Loading...</p>
  <p slot="error">An error occurred.</p>
</Suspense>

The <Suspense> component here is tied into the suspend call we made while fetching data. If any child components (or any of their children) aren't ready to display yet, this component will just show "Loading...". Once the data comes in, the loading indicator is discard and our components are shown.

Isn't this just #await?

{#await} in templates is a powerful tool and these tools do not replace it. If all data fetching and loading indicators happen in a single component, then that is a simpler way to achieve these same goals.

The difference happens when data loading is spread across multiple components. A change to the APIs <Evolution> depends on would only impact that single component. The loading indicators on our main page do not care which data is needed or where it comes from. If the <Link> component referenced in our <Evolution> component also fetched data of its own (e.g. prefetching an image of the Pokemon) we don't have to change any code here at all.

Conclusion

This isn't meant to be an in depth explanation for using any of the libraries mentioned here. For that, consult their documentation:

Instead, hopefully it illuminates their motivations for existing and what problems they are trying to solve. You can find a full fledged example of the techniques discussed here: https://pokemon-suspense-demo.vercel.app/


This content originally appeared on DEV Community and was authored by Brian K


Print Share Comment Cite Upload Translate Updates
APA

Brian K | Sciencx (2021-10-26T00:10:46+00:00) Suspense in Svelte: Writing Components That Don’t Care. Retrieved from https://www.scien.cx/2021/10/26/suspense-in-svelte-writing-components-that-dont-care/

MLA
" » Suspense in Svelte: Writing Components That Don’t Care." Brian K | Sciencx - Tuesday October 26, 2021, https://www.scien.cx/2021/10/26/suspense-in-svelte-writing-components-that-dont-care/
HARVARD
Brian K | Sciencx Tuesday October 26, 2021 » Suspense in Svelte: Writing Components That Don’t Care., viewed ,<https://www.scien.cx/2021/10/26/suspense-in-svelte-writing-components-that-dont-care/>
VANCOUVER
Brian K | Sciencx - » Suspense in Svelte: Writing Components That Don’t Care. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/26/suspense-in-svelte-writing-components-that-dont-care/
CHICAGO
" » Suspense in Svelte: Writing Components That Don’t Care." Brian K | Sciencx - Accessed . https://www.scien.cx/2021/10/26/suspense-in-svelte-writing-components-that-dont-care/
IEEE
" » Suspense in Svelte: Writing Components That Don’t Care." Brian K | Sciencx [Online]. Available: https://www.scien.cx/2021/10/26/suspense-in-svelte-writing-components-that-dont-care/. [Accessed: ]
rf:citation
» Suspense in Svelte: Writing Components That Don’t Care | Brian K | Sciencx | https://www.scien.cx/2021/10/26/suspense-in-svelte-writing-components-that-dont-care/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.