1

I am using SvelteKit with Supabase. Whenever the form is submitted I would like to see the DOM live update. However, it takes a refresh to see the changes. How would I live update the DOM whenever a new row is inserted into the table?

<script>
    import { supabase } from '$lib/supabaseClient'

    const getData = async function() {
        const { data, error } = await supabase
        .from('scores')
        .select('*')

        return data
    }

    let newRowName = '';
    let newRowScore = 0;
    const postData = async function(nameVal, scoreVal) {
        const { data, error } = await supabase
        .from('scores')
        .insert([{ name: nameVal, score: scoreVal }])
    }
</script>

{#await getData()}
    <p>Waiting...</p>
{:then data}
    {#each data as singleData}
        <p>{singleData.name}: {singleData.score}</p>
    {/each}
{:catch error}
    <p>Error occured</p>
{/await}

<form on:submit|preventDefault="{() => postData(newRowName, newRowScore)}">
    <label for="name">Name:</label>
    <input type="text" id='name' bind:value='{newRowName}' required />
    <label for="score">Score:</label>
    <input type="number" id='score' bind:value='{newRowScore}' required />

    <button>Add row</button>
</form>

2 Answers2

1

hilo!

The only way to do something when the data is changed is by using supabase realtime however i am not 100% how one would reload the DOM but i would try to use goto(current route). I do not have i computer accesible so i cannot confirm that that would reload the DOM although i believe it should.

This is 1 way it could be solved using what i just said:

(async () => {const mySubscription = supabase
  .from('scores')
  .on('insert', (payload) => {
    goto(current route)
  })
  .subscribe()})()

Tho that would mean that if anyone where to insert to the table it would reload which i would assume isn’t good but i guess you could just use goto() in the post function as such:

const postData = async function(nameVal, scoreVal) {
    const { data, error } = await supabase
    .from('scores')
    .insert([{ name: nameVal, score: scoreVal }])
 if (data) goto(route)
}

As long as goto() indeed does reload the DOM, it solves the problem that the user would have to reload the page manually but… the page is reloaded, not updated

  • I acctually think you can scrap the first idea completely. There are just so many bad things with that solution. – Sebastian Trygg Aug 24 '22 at 20:46
  • That’s a clever approach to solve the problem, even though a reload is required which isn’t optimal. However, not needing additional dependencies like supabase realtime is also a plus. I’ll give it a shot, thank you! –  Aug 24 '22 at 20:51
0

If you only care about rows that you have inserted yourself via the current page, you can probably just update the local state.

Something along the lines of this:

// Local state, so it can be updated
let rows = null;

const getData = async function() {
    const { data, error } = await supabase
        .from('scores')
        .select('*');

    // Update local state only
    rows = data;
}

// ...

const postData = async function(nameVal, scoreVal) {
    const { data, error } = await supabase
        .from('scores')
        .insert([{ name: nameVal, score: scoreVal }])

    // Assuming that data will be the row
    rows = [...rows, data];
}
{#await getData()}
    <p>Waiting...</p>
{:then _}
    {#each rows as row}
        <p>{row.name}: {row.score}</p>
    {/each}
{:catch error}
    <p>Error occured</p>
{/await}
H.B.
  • 166,899
  • 29
  • 327
  • 400