0

Context

I'm using Svelte-Flow with Sevelte 5 for some project. To scale I want to have the object defining my node pushed to indexedDB. To keep it in sync and don't dodata handling twice, I want to sync my reactive object holding the nodes with the database.

<script>
    let nodes = state.raw([]);

    const some_new_node = {"type": "textNode", data: ["..."]}

    async function addNode() {
        // Let's make it simple and use dexie.js for interacting with indexedDB -> nodes is a store in a dexie-Database
        const new_id = await db.nodes.add(some_new_node);

        const some_new_node_with_id = {id: new_id, "type": ... };
        nodes = [...nodes, some_new_node_with_id];
    }

</script>

<button onclick:addNode></button>
<SvelteFlow bind:nodes> ... </SvelteFlow>

Problem

As I had to figure out like many more, Svelte 5 runes are not intended to work with async-functions due to race conditions. Thus, in the line with the await reactivity breaks and nodes is never updated.

So usually for async stuff like this I would now have to try out some solution using the {#await ...} syntax. The thing is: As I'm binding nodes and SvelteFlow expects for it's internals the given format, I'm kinda stuck how to solve this.

Any ideas how to combine Svelte-Flow with Svelte 5 with async database retrievals?




Full minimum example

// main file

<script>
    import { SvelteFlow } from '@xyflow/svelte';
    import '@xyflow/svelte/dist/style.css';

    import { db } from '$lib/database/dexdb.js'; // Assuming you have a Dexie database setup in this file

    let nodes = $state.raw([]);
    let edges = $state.raw([]);

    // Does not work
    async function addNodeAsync() {
        // Let's make it simple and use dexie.js for interacting with indexedDB -> nodes is a store in a dexie-Database
        const new_id = await db.nodes.add({ type: 'input', position: { x: 100, y: 100 } });
        console.log('New node added with ID:', new_id);
        
        const some_new_node_with_id = { id: new_id, type: 'input', position: { x: 100, y: 100 } };
        nodes = [...nodes, some_new_node_with_id];
    }

    // Works fine (reavtive)
    function addNodeSync() {
        const new_id = Math.random().toString(36).substring(2, 9);

        const some_new_node_with_id = { id: new_id, type: 'input', position: { x: 100, y: 100 } };
        nodes = [...nodes, some_new_node_with_id];
    }
</script>

<button onclick={addNodeAsync}>New Node Async</button>
<button onclick={addNodeSync}>New Node Sync</button>
<div style:width="100vw" style:height="100vh">
    <SvelteFlow bind:nodes bind:edges fitView></SvelteFlow>
</div>

// Dexie-DB (IndexedDB)
import Dexie from 'dexie';

export const db = new Dexie('ermStore');
db.version(1).stores({
    nodes: '++id'
});

3
  • await in event handlers should be no issue on its own. It only really matters if the function is called in an effect (or the template, which runs in an effect), where dependencies will no longer be tracked correctly. Changes to state should still cause updates where the state is being used. Commented Jun 24 at 16:08
  • I tried updating nodes after some awaited delay and it worked just fine. If you have a problem with reactivity, please provide a minimal but complete reproduction. Commented Jun 24 at 17:41
  • THB @brunnerh I guessed for anybody having used Svelte-Flow before the example was already minimal enough, but if you require to fill the gaps I added you an example. Bottom Line: Sync Works, Async not. Anyhow, if you already know the solution I'm glad to hear :) Commented Jun 25 at 0:06

1 Answer 1

1

The id has to be a string, in the async function the id is a number.
As soon as you change it to id: new_id.toString(), it works as expected.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.