Svelte: Communication between components through the Store
Tags: Web Components, Svelte 3, JavaScript, Sveltejs, D3js

Svelte: Communication between components through the Store

Implement communication between unrelated components using Svelte's built in store CertosinoLab Sep 2·3 min read

Photo by Jess Bailey on Unsplash

Svelte’s store: A short Introduction

In Svelte, state management is simplified by the presence of an internal store. This store translates into an object that has a series of methods, some are used to manage operations on it, others are used to notify the other parts of the application when the value of the store changes.

In Svelte we have three types of stores: Writable, Readable, Derived.

In this article we will only use the writable type.

Find more on: API Docs • Svelte

What we will build

A simple application with a button and a d3.js horizontal bar chart. There are two components: the button and the chart container

Getting Started

You can download and run the basic project template with following commands:

npx degit sveltejs/template svelte-d3-1

cd svelte-d3-1

npm install

npm run dev

In this tutorial we will use d3.js, so install it

npm i d3

Let’s Code

The data of the chart is stored in a store called sharedData.

Inside store.js, we got

import {writable, derived} from 'svelte/store'

export const sharedData = writable([30, 86, 168, 281, 303, 365])

sharedData have a start value of [30, 86, 168, 281, 303, 365], its the array that we will pass to d3.js chart.

This data change everytime you click on the Fetch Data button, as in the FetchButton component we have the fetchData method which, when invoked, change the store values.

Let’s take a look at our component: DataFetchButton.svelte

<script>

import {sharedData} from "../store";



function generateRandomNumber() {

return Math.floor(Math.random() * 600)

}



function setNewData() {

let newData = [];

for(let i = 0; i < 6; i++) {

newData.push(generateRandomNumber());

}

return newData;

}



function fetchData() {

sharedData.set(setNewData())

}

</script>



<style>

.fetch-button {

float: left;

cursor: pointer;

margin-top: 10px;

}

</style>



<button class="fetch-button" on:click={fetchData}>Fetch Data</button>

Now we can create our ChartContainer.svelte component:

<script>

import {sharedData} from "../store";

import { onMount } from 'svelte';

import * as d3 from 'd3';



let el;

let data;



onMount(() => {

data = $sharedData;



d3.select(el)

.selectAll("div")

.data(data)

.enter()

.append("div")

.style("width", function(d) {

return d + "px";

})

.text(function(d) {

return d;

});

});

</script>



<style>

.chart :global(div) {

font: 10px sans-serif;

background-color: steelblue;

text-align: right;

padding: 3px;

margin: 1px;

color: white;

}

</style>



<div bind:this={el} class="chart"></div>

as you can see, we assign $sharedData to the data variable, which is used to initialize data in the chart.

If you click on the button Fetch Data at this moment the data does not change, so the chart remains the same, to solve the problem one way can be to make a re-render of the chart component (obviously there are other ways to solve the problem).

So take a look at App.svelte component

<script>

import ChartContainer from './components/ChartContainer.svelte'

import DataFetchButton from "./components/DataFetchButton.svelte";

import {sharedData} from "./store";



let chartData;



sharedData.subscribe(value => {

console.log(value);

chartData = value;

});

</script>



<main>

{#key chartData}

<ChartContainer />

{/key}

<DataFetchButton />

</main>



<style>

main {

text-align: center;

padding: 1em;

max-width: 240px;

margin: 0 auto;

}



h1 {

color: #ff3e00;

text-transform: uppercase;

font-size: 4em;

font-weight: 100;

}



@media (min-width: 640px) {

main {

max-width: none;

}

}

</style>

Svelte have an awesome block called #key, to this block you can assign a property, everytime the value of this property change the component inside the block get re-rendered (of course this feature should be used with caution).

thanks to shared Data.subscribe every time the value of the sharedData store changes we change the value of the variable passed as a key (chartData), so we re-render the chart component

Github Repository

You can download the complete code here: GitHub — CertosinoLab/mediumarticles at svelte-d3–1

Thank you for reading!