Comments (3)
Hello, I end up with something like that to reuse on different form/action.
//@types/action.d.ts
import { FieldValues, FormErrors } from "@modular-forms/solid";
import { Action } from "@solidjs/router";
export type ActionForm<Schema extends FieldValues> = Action<
[data: Schema],
{ success?: boolean; error?: string; fields?: FormErrors<Schema> } | void
>;
// autocomplete on fields from TS
//lib/utils.ts
export function flatIssues<K extends string | number>(
issues: SchemaIssues,
): { [key in K]?: string } {
let errors: { [key in K]?: string } = issues ? {} : {};
return issues.reduce((acc, issue) => {
if (
issue.path?.every(
({ key }) => typeof key === "string" || typeof key === "number",
)
) {
const key = issue.path!.map(({ key }) => key).join(".") as K;
if (acc[key]) {
acc[key] = acc[key] + "\n" + issue.message; // merge multiple issues, split in components
} else acc[key] = issue.message;
}
return acc;
}, errors);
}
//login.tsx
export default function Index() {
const action = useAction(login);
const submission = useSubmission(login);
const [loginForm, { Form, Field }] = createForm<LoginForm>({
validate: valiForm(LoginSchema),
});
const handleSubmit: SubmitHandler<LoginForm> = async (values) => {
await action(values);
if (submission.result) {
const { error = "", fields = {} } = submission.result;
throw new FormError<LoginForm>(error, fields);
}
};
return ( ... );
};
const LoginSchema = v.object({ ... })
type LoginForm = v.Input<typeof LoginSchema>;
const login: ActionForm<LoginForm> = action(async (data) => {
"use server";
const result = v.safeParse(LoginSchema, data);
if (!result.success) {
const errors = flatIssues<keyof LoginForm>(result.issues);
return { fields: errors };
}
const { username, password } = result.output;
// db call
if (failed) return { error: "user does not exist" };
// all good
throw redirect("/");
}, "login");
from modular-forms.
Okay I think I've figured it out but it seems a bit quirky, please let me know if there is a better way?
Action code:
const login = action(async (values: LoginForm) => {
"use server";
const result = safeParse(LoginSchema, values);
if (!result.success) {
const flattened = flatten<typeof LoginSchema>(result.issues);
const errors = Object.entries(flattened.nested).reduce(
(acc, [key, value]) => {
acc[key] = value[0];
return acc;
},
{} as { [key: string]: string },
);
if (flattened.root && flattened.root.length > 0) {
return new FormError<LoginForm>(flattened.root[0], errors);
}
return new FormError<LoginForm>(errors);
}
return new FormError<LoginForm>("Email exists in database");
});
Submit code:
const [loginForm, { Form, Field }] = createForm<LoginForm>({});
const act = useAction(login);
const sub = useSubmission(login);
const handleSubmit: SubmitHandler<LoginForm> = async (values) => {
await act(values);
if (sub.result) {
Object.entries(sub.result.errors).forEach(([field, message]) => {
setError(loginForm, field as keyof LoginForm, message);
});
throw new FormError<LoginForm>(sub.result.message);
}
};
from modular-forms.
Hey, I haven't had time to take a closer look at the new SolidStart beta release. I plan to integrate it in the future with a nice API and DX, but that will take some time.
from modular-forms.
Related Issues (20)
- [Qwik] Form state is reset after action returns an error HOT 1
- [React]: Preact Signals Dependency Update HOT 11
- [Valibot/i18n] Client side validation is not translated HOT 2
- [Bug] Todo - Move First to End - Warning: Cannot update a component (`ForwardRef`) while rendering a different component (`Field`) HOT 3
- [Feature] Ability to configure different validations to run at different times HOT 1
- [Bug]: FormError is invoked only once on Qwik v1.4.5 HOT 5
- valiForm doesn't execute custom validation properly HOT 4
- hello facing types errors HOT 1
- Form submitted when filed has error HOT 2
- [Question] How to implement a controlled component contains multiple fields? HOT 3
- formAction$ code is not executed if Form component has "class" attribute HOT 8
- [Question] Render props pattern HOT 2
- Form action triggers drizzle polyfill issues. HOT 2
- Make the second parameter of the `formAction$` optional HOT 6
- loginForm.submitting not reactive
- Prevent Double Submit HOT 8
- Form action response is optional before form submit HOT 1
- Can I use modular-forms with action from "@solidjs/router"? HOT 3
- [React] Feature Request: Decouple Form and FormStore creation from components.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from modular-forms.