morpheus
morpheus

Reputation: 20380

Parent component does not update if child component modifies Svelte store

I am new to Svelte. I am creating a writeable store like this:

export const db = writable(collections);

example collections is shown below for clarity:

export const collections = {
    "shakespeare": {
        "documents": {
            "merchant-of-venice": {
                "text": "",
                "size": 117826,
            },
            "julius-caesar": {
                "text": "",
                "size": 224,
            },
            "twelfth-night": {
                "text": "",
                "size": 533,
            },
        },
        "size": 416,
    },
    // more like this...

I am writing a component which will allow user to upload a file to the writable store. To do this I have a parent component A and a child component B that actually does the heavy work.

Parent component A:

<script>
  import { db } from '$lib/memstore.js'
  export let documents = $db[collection].documents;
</script>
...
{#each Object.entries(documents) as [name, document]}
  // render in UI
{/each}
...
<B>Upload Button</B>

Child Component B:

import { db } from './memstore';
let documentStore = $db[collection].documents;

async function uploadFiles() {
    ...
    documentStore[id] = {
        text: text,
        size: text.length
    }
}

I can run the code and there is no error. The problem is that the parent component does not update. There is no re-render pass when a file is uploaded and documentStore is modified by the child component B. How can I fix it?

Upvotes: 2

Views: 536

Answers (1)

Stephane Vanraes
Stephane Vanraes

Reputation: 16451

Your problem lies in that doing let documents = $db[collection].documents kind of disconnects the documents variable from the store, from now on Svelte will think you are working purely on a local variable.

Instead you should modify the store itself when adding or removing items and use reactivity to update any properties you extract from it.

for example:

$: documents = $db["shakespeare"].documents

function add() {
  $db["shakespeare"].documents["the-taming-of-the-shrew"] = {}
}

with this code the variable documents will be kept in sync at all times with the value in the store, in the add function I modify the store directly, thanks to the reactivity this means that documents will be updated as well.

this is of course a very crude example but it shows the basic principle, you can easily adapt and develop this further if you dig a bit more in how stores and reactivity work in Svelte.

Upvotes: 4

Related Questions