在SvelteKit中实现一个在执行操作期间触发的加载旋转器。

huangapple go评论129阅读模式
英文:

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"

英文:

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

答案1

得分: 6

以下是要翻译的内容:

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

英文:

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:

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

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

答案2

得分: 0

Have you considered using the {#await} block? What you can do is when you fetch the database it triggers the await block and when it's done, you can decide from there if you want to continue login or send to the registration page. Refer to: https://svelte.dev/tutorial/await-blocks

So it can looks something like:

<script>
  let data;
  async function formSubmit() {
    data = await fetchData();

    ...
  }
</script>

{#await data}
  <Spinner />
{:then receivedData}
  <!-- Decide to send to registration or not -->
  <!-- you can either use the receivedData or just omit it -->
{:catch}
 <!-- Handle error -->
{/await}
英文:

Have you considered using the {#await} block?
What you can do is when you fetch the database it triggers the await block and when it's done, you can decide from there if you want to continue login or send to the registration page.

Refer to: https://svelte.dev/tutorial/await-blocks

So it can looks something like:

&lt;script&gt;
  let data;
  async function formSubmit() {
    data = await fetchData();

    ...
  }
&lt;/script&gt;

{#await data}
  &lt;Spinner /&gt;
{:then receivedData}
  &lt;!-- Decide to send to registration or not --&gt;
  &lt;!-- you can either use the recievedData or just omit it --&gt;
{:catch}
 &lt;!-- Handle error --&gt;
{/await}

答案3

得分: 0

我不得不将第一个答案重新排序如下:

  const formSubmit: SubmitFunction = ({ form, data, action, cancel }) =&gt; {
    formLoading = true;
    return async ({ update }) =&gt; {
      await update(); // 等待此操作完成
      formLoading = false;
    };
  };
英文:

I had to reorder the first answer like this:

  const formSubmit: SubmitFunction = ({ form, data, action, cancel }) =&gt; {
    formLoading = true;
    return async ({ update }) =&gt; {
      await update(); // Wait for this to complete
      formLoading = false;
    };
  };

huangapple
  • 本文由 发表于 2023年6月29日 19:51:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76580769.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定