Throw form errors
Modular Forms has built-in error handling with the FormError
class to easily display individual errors when submitting a form.
Throw general error
General errors are errors that affect the entire form and can be displayed via the response
state in the UI, e.g. above the submit button.
Client-side errors
When processing the form client-side via the onSubmit$
event listener, any error thrown is automatically caught and added to the response
state.
To throw custom errors to be displayed to the user, you can use our FormError
class. It inherits from the default Error
class and can contain a general error message as well as error messages for individual fields. More about this in a moment.
import { $, component$ } from '@builder.io/qwik';
import { routeLoader$ } from '@builder.io/qwik-city';
import type { InitialValues, FormError } from '@modular-forms/qwik';
import { formAction$, valiForm$ } from '@modular-forms/qwik';
import * as v from 'valibot';
const LoginSchema = v.object({
email: v.pipe(
v.string(),
v.nonEmpty('Please enter your email.'),
v.email('The email address is badly formatted.')
),
password: v.pipe(
v.string(),
v.nonEmpty('Please enter your password.'),
v.minLength(8, 'You password must have 8 characters or more.')
),
});
type LoginForm = v.InferInput<typeof LoginSchema>;
export const useFormLoader = routeLoader$<InitialValues<LoginForm>>(() => ({
email: '',
password: '',
}));
export default component$(() => {
const [loginForm, { Form, Field }] = useForm<LoginForm>({
loader: useFormLoader(),
validate: valiForm$(LoginSchema),
});
const handleSubmit: SubmitHandler<LoginForm> = $((values, event) => {
if (error) {
throw new FormError<LoginForm>('An error has occurred.');
}
});
return (
<Form onSubmit$={handleSubmit}>
<div>…</div>
<div>{loginForm.response.message}</div>
<button type="submit">Login</button>
</Form>
);
});
Server-side errors
For server-side errors, we are a bit more cautious, as secret information might be preserved here and therefore only output a generic error message for all errors that are not an instance of our FormError
class. So, to intentionally output custom errors to the user, our FormError
class must be used.
export const useFormAction = formAction$<LoginForm>((values) => {
if (error) {
throw new FormError<LoginForm>('An error has occurred.');
}
}, valiForm$(LoginSchema));
Throw field error
Field errors are errors that are assigned to a specific field and added to its state. In addition to a general error message, you can also add an error message to specific fields using the second argument of the FormError
class constructor.
if (error) {
throw new FormError<LoginForm>('An error has occurred.', {
email: 'This email has been blacklisted.',
});
}
Field errors only
To not display a general error message and instead display only errors of individual fields, you can simply omit the general message.
if (error) {
throw new FormError<LoginForm>({
email: 'This email has been blacklisted.',
});
}