1st failure attempt doesn't print an error, its undefined
after migrating to v1
#527
-
I used Repro in app/routes/_index.tsximport { getFormProps, getInputProps, useForm } from '@conform-to/react'
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
import { ActionFunctionArgs, json, redirect } from '@remix-run/node'
import { Form, useActionData } from '@remix-run/react'
import { z } from 'zod'
import { ErrorMessage } from '~/components/ErrorMessage'
import { useIsPending } from '~/utils/misc'
export const LoginFormSchema = z.object({
email: z
.string({ required_error: 'Email is required' })
.email('Invalid email address'),
password: z
.string({ required_error: 'Password is required' })
.min(6, 'Password must be at least 6 characters long'),
})
export type User = {
first_name: string
last_name: string
email: string
password: string
}
export async function login({
email,
password,
}: Pick<User, 'email' | 'password'>) {
return email === '[email protected]' && password === 'aaaaaa'
}
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData()
const submission = await parseWithZod(formData, {
schema: LoginFormSchema.transform(async (data, ctx) => {
const session = await login(data)
console.log({ session })
if (!session) {
ctx.addIssue({
path: ['email'],
code: z.ZodIssueCode.custom,
message: 'Invalid email or password',
})
return z.NEVER
}
return { ...data, session }
}),
async: true,
})
console.log({ submission })
console.log(submission.status !== 'success')
if (submission.status !== 'success' || !submission.value?.session) {
console.log('inside')
return json(
{ result: submission.reply({ hideFields: ['password'] }) },
{ status: submission.status === 'error' ? 400 : 200 }
)
}
console.log('hi')
const { session } = submission.value
if (!session) {
return json(
{ status: 'error', result: submission.reply() },
{ status: 400 }
)
}
return redirect('/dashboard', {
headers: {
'Set-Cookie': 'LoggedIn',
},
})
}
export default function Login() {
const actionData = useActionData<typeof action>()
const isPending = useIsPending()
const [form, fields] = useForm({
id: 'login-form',
constraint: getZodConstraint(LoginFormSchema),
lastResult: actionData?.result,
onValidate({ formData }) {
return parseWithZod(formData, { schema: LoginFormSchema })
},
shouldValidate: 'onBlur',
})
return (
<div className="max-w-96">
<h1 className="pl-2 mb-2 text-3xl text-amber-500">
Remix + Conform + Login
</h1>
<div>
<Form
role="form"
method="POST"
{...getFormProps(form)}
className="flex flex-col"
>
<input
{...getInputProps(fields.email, { type: 'email' })}
id="email"
aria-label="Enter your email"
placeholder="email"
name="email"
className="p-2 m-2"
/>
{fields.email.errors && (
<ErrorMessage>{fields.email.errors}</ErrorMessage>
)}
<input
{...getInputProps(fields.email, { type: 'password' })}
id="password"
aria-label="Enter your password"
placeholder="password"
name="password"
className="p-2 m-2"
/>
{fields.password.errors && (
<ErrorMessage>{fields.password.errors}</ErrorMessage>
)}
<button type="submit" className="underline text-sky-500 py-4">
{isPending ? 'Loading' : 'Login'}
</button>
</Form>
</div>
</div>
)
} This used to work before v1 migration. Now it doesn't. On 1st failure attempt, it doesn't prints failure error. Only on 2nd attempt & later, it prints properly. Refresh to test again. How do I solve it? I made a smallest repro above if you wanna test but I'm sure its something small. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 10 replies
-
@edmundhung i think this is a bug as i triple-checked my code. it is very similar to what others have done. it used to work fine before upgrading my remix app to conform v1. i get the error logged into the console so database is working fine. the json gets returned but it isn't printed in react. for signup, it fails to print first time if i try to create a duplicate account. |
Beta Was this translation helpful? Give feedback.
-
@edmundhung i press enter twice. see the 1st time there's no error. it only shows up 2nd time. you can clone & see the error if its not showing on stackblitz. it shows for me tho. remix-conform-login.mp4meanwhile, i got this in console: {}
{}
{ session: false }
{
"status": "error",
"payload": {
"email": "[email protected]",
"password": "123456"
},
"error": {
"email": [
"Invalid email or password"
]
}
}
true
inside
{ session: false }
{
"status": "error",
"payload": {
"email": "[email protected]",
"password": "123456"
},
"error": {
"email": [
"Invalid email or password"
]
}
}
true
inside |
Beta Was this translation helpful? Give feedback.
I have improved how Conform will revalidate on blur on v1.1.0-pre.0. Please give it a try.