javascriptsveltesveltekitpocketbase

Implementing a loading spinner in sveltekit that is triggered during an action


I have a simple form having email, password and confirmPassword. I use action to handle this. I want to implement a spinner that will be triggered for the following actions

  1. Checking if user is currently existing in the db
  2. If no, then proceed for registration

I am using pocketbase

Following is my action.

import { superValidate } from 'sveltekit-superforms/server';
import { redirect } from '@sveltejs/kit';
import { fail } from '@sveltejs/kit';

import { loginSchema } from '$lib/schema/zodschema';
import { ClientResponseError } from 'pocketbase';

export const load = async () => {
    const form = await superValidate(loginSchema);
    return { form };
};

export const actions = {
    default: async ({ locals, request }) => {
        const form = await superValidate(request, loginSchema);


        try {

            const { email } = form.data
            const records = await locals.pb.collection('test').getFullList();
            const userRecords = records.filter(value => value.email === form.data.email);

            if (userRecords.length > 0) {

                const existingUser = userRecords[0]

                if (existingUser && existingUser.verified) {
                    return {

                        accountCreated: false,
                        message: 'The user records exists. Proceed to login instead',
                        isVerified: true,

                    }
                } else {


                    return {

                        accountCreated: false,
                        message: 'The user record exists. You have to verify to access',
                        isVerified: false,


                    }
                }
            } else {
                await locals.pb.collection('test').create(form.data);



                return {

                    accountCreated: true,
                    message: 'The user record is successfully created',
                    isVerified: false,
                }
            }



        } catch (error) {
            // Handle the error

            if (error instanceof ClientResponseError) {
                return {
                    error: error.message,
                    isLoading: false
                }
            }
        }
    }
};

In the above, I could set a boolean like

let isLoading = true

Then set it to false at different stages. But the problem is how to access the isLoading status in the client (both initial and updated state).

I tried stores only to find out later that stores cannot be used to share the state between the client and server.

Is there an alternative approach to achieve this?

Thanks


Solution

  • It is not entirely clear to me, but it seems that you are trying to use Sveltekit form actions. Also, it is not clear to me why the loader needs to change during the server load.

    What I would recommend is that you use a loading boolean in the client when the request starts and ends using progressive enhancement:

    <script>
        import { enhance } from '$app/forms';
    
        /** @type {import('./$types').PageData} */
        export let data;
    
        let formLoading = false;
    </script>
    
    ...
    {#if formLoading}
        Loading...
    {/if}
    ...
    <form action="?/..." method="post" use:enhance={() => {
        formLoading = true;
        return async ({ update }) => {
            formLoading = false;
            update();
        };
    }}>
        <button>SUBMIT</button>
    </form>
    
    

    Relative documentation: https://kit.svelte.dev/docs/form-actions#progressive-enhancement