fabian-hiller / modular-forms

The modular and type-safe form library for SolidJS, Qwik and Preact
https://modularforms.dev
MIT License
1.04k stars 55 forks source link

[Bug]: FormError is invoked only once on Qwik v1.4.5 #196

Open wanjohiryan opened 7 months ago

wanjohiryan commented 7 months ago

The issue:

I am trying to throw an error when the username already exists (after the server tries querying the db on form submit). However, i have noticed this weird bug where, if the user changes the username value, and the username already exist, then i try to throw a new FormError. it won't work... That is the field.error will return nothing.

It works at first though, then all the subsequent errors will not show.

// eslint-disable-next-line @typescript-eslint/no-unused-vars
    const [state, { Form, Field, }] = useForm<Form>({
        loader: useFormLoader(),
        validate: valiForm$(Schema),
    });

    const handleSubmit = $<SubmitHandler<Form>>(async (values) => {
        const response = await fetch('/account', {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify(values)
        })
        const user = await response.json()

        if (user) {

        } else {
            console.log("username error")
            throw new FormError<Form>({
                name: 'An account with this username already exists.'
            });
        }
    });

Oh, and if i try to do it on the server (same exact code but using useFormAction) no errors will be shown.

wanjohiryan commented 7 months ago

Funny, if i use the form.response.message, instead of the scoped field.error to get display the error 'An account with this username already exists., it works... even when i change the value multiple times, and the username exists.

so here is my work around

throw new FormError<Form>('An account with this username already exists.',);
// remove this
// {
//     name: 'An account with this username already exists.'
// }

Then have the jsx look like this

<Field name="name">
     {(field, props) => (
        <>
            <label class='text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'>Username</label>
            <input {...props} placeholder="ryan" type="name" value={field.value} class='focus:ring-[0.1875rem] focus:ring-accent flex h-9 w-full rounded-md bg-[#E8F0FE] text-black px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-black/20 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50' />
            {field.error && (<p class='text-[0.8rem] font-medium text-red-500' >{field.error}</p>)}
            {form.response.message && (<p class='text-[0.8rem] font-medium text-red-500' >{form.response.message}</p>)}
            <p class='text-[0.8rem] text-muted-foreground'>This is your public display name. It can be your real name or a pseudonym.</p>
         </>
       )}
</Field>
wanjohiryan commented 7 months ago

Here is my two cents, i think it has to do with how you guys handle the field errors. It looks like disrupting the field state after:

  1. throwing an error on submission,
  2. throw another error if the form validation does not work
  3. then try to throw another error when on user submission will return a blank field error.

Thanks for your great work, Fabian. :)

fabian-hiller commented 7 months ago

Looks like a signal bug or problem in Qwik or do you thing it is related to our source code?

wanjohiryan commented 7 months ago

I am not using any Qwik useSignal code anywhere (from my snippet) so it most likely is stemming from somewhere in your source code.

How do you handle errors on submission per field?

fabian-hiller commented 7 months ago

In encountering myself some wired signal behavior in Qwik. I hope this gets better with v2. I am in exchange with the Qwik team. If you provide me with a minimal reproduction on StackBlitz I can try to investigate the problem. Here is a template: https://stackblitz.com/edit/modular-forms-qwik?file=src/routes/login/index.tsx