Basic form handling and Zod validation with vovk-zod.
1import { z } from 'zod';
2
3export const userSchema = z
4 .object({
5 name: z.string().min(2).max(20),
6 email: z.string().email(),
7 })
8 .strict();
1import { z } from 'zod';
2
3export const userSchema = z
4 .object({
5 name: z.string().min(2).max(20),
6 email: z.string().email(),
7 })
8 .strict();
1import { z } from 'zod';
2
3export const userSchema = z
4 .object({
5 name: z.string().min(2).max(20),
6 email: z.string().email(),
7 })
8 .strict();
1import { z } from 'zod';
2
3export const userSchema = z
4 .object({
5 name: z.string().min(2).max(20),
6 email: z.string().email(),
7 })
8 .strict();
1import { prefix, post, VovkRequest } from 'vovk';
2import vovkZod from 'vovk-zod';
3import { z } from 'zod';
4import { userSchema } from '../../zod';
5
6@prefix('form')
7export default class FormController {
8 @post('create-user', { cors: true })
9 @vovkZod(userSchema)
10 static async createUser(req: VovkRequest<z.infer<typeof userSchema>>) {
11 const { name, email } = await req.json();
12
13 return {
14 success: true,
15 user: { name, email },
16 };
17 }
18}
1import { prefix, post, VovkRequest } from 'vovk';
2import vovkZod from 'vovk-zod';
3import { z } from 'zod';
4import { userSchema } from '../../zod';
5
6@prefix('form')
7export default class FormController {
8 @post('create-user', { cors: true })
9 @vovkZod(userSchema)
10 static async createUser(req: VovkRequest<z.infer<typeof userSchema>>) {
11 const { name, email } = await req.json();
12
13 return {
14 success: true,
15 user: { name, email },
16 };
17 }
18}
1import { prefix, post, VovkRequest } from 'vovk';
2import vovkZod from 'vovk-zod';
3import { z } from 'zod';
4import { userSchema } from '../../zod';
5
6@prefix('form')
7export default class FormController {
8 @post('create-user', { cors: true })
9 @vovkZod(userSchema)
10 static async createUser(req: VovkRequest<z.infer<typeof userSchema>>) {
11 const { name, email } = await req.json();
12
13 return {
14 success: true,
15 user: { name, email },
16 };
17 }
18}
1import { prefix, post, VovkRequest } from 'vovk';
2import vovkZod from 'vovk-zod';
3import { z } from 'zod';
4import { userSchema } from '../../zod';
5
6@prefix('form')
7export default class FormController {
8 @post('create-user', { cors: true })
9 @vovkZod(userSchema)
10 static async createUser(req: VovkRequest<z.infer<typeof userSchema>>) {
11 const { name, email } = await req.json();
12
13 return {
14 success: true,
15 user: { name, email },
16 };
17 }
18}
1'use client';
2import { useState, type FormEvent } from 'react';
3import { FormController } from 'vovk-client';
4import type { VovkReturnType } from 'vovk';
5
6export default function FormExample() {
7 const [response, setResponse] = useState<VovkReturnType<typeof FormController.createUser> | null>(null);
8 const [error, setError] = useState<Error | null>(null);
9 const [name, setName] = useState('');
10 const [email, setEmail] = useState('');
11 const [disableClientValidation, setDisableClientValidation] = useState(false);
12 const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
13 e.preventDefault();
14 try {
15 setResponse(
16 await FormController.createUser({
17 body: { name, email },
18 disableClientValidation,
19 })
20 );
21 setError(null);
22 } catch (e) {
23 setError(e as Error);
24 setResponse(null);
25 }
26 };
27
28 return (
29 <form onSubmit={onSubmit}>
30 <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
31 <input type="text" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
32 <label className="block mb-4">
33 <input
34 type="checkbox"
35 className="mr-2"
36 checked={disableClientValidation}
37 onChange={(e) => setDisableClientValidation(e.target.checked)}
38 />
39 Disable client-side validation
40 </label>
41 <button>Submit</button>
42
43 {response && (
44 <div className="text-left">
45 <h3>Response:</h3>
46 <pre>{JSON.stringify(response, null, 2)}</pre>
47 </div>
48 )}
49
50 {error && <div className="overflow-auto">❌ {String(error)}</div>}
51 </form>
52 );
53}
1'use client';
2import { useState, type FormEvent } from 'react';
3import { FormController } from 'vovk-client';
4import type { VovkReturnType } from 'vovk';
5
6export default function FormExample() {
7 const [response, setResponse] = useState<VovkReturnType<typeof FormController.createUser> | null>(null);
8 const [error, setError] = useState<Error | null>(null);
9 const [name, setName] = useState('');
10 const [email, setEmail] = useState('');
11 const [disableClientValidation, setDisableClientValidation] = useState(false);
12 const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
13 e.preventDefault();
14 try {
15 setResponse(
16 await FormController.createUser({
17 body: { name, email },
18 disableClientValidation,
19 })
20 );
21 setError(null);
22 } catch (e) {
23 setError(e as Error);
24 setResponse(null);
25 }
26 };
27
28 return (
29 <form onSubmit={onSubmit}>
30 <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
31 <input type="text" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
32 <label className="block mb-4">
33 <input
34 type="checkbox"
35 className="mr-2"
36 checked={disableClientValidation}
37 onChange={(e) => setDisableClientValidation(e.target.checked)}
38 />
39 Disable client-side validation
40 </label>
41 <button>Submit</button>
42
43 {response && (
44 <div className="text-left">
45 <h3>Response:</h3>
46 <pre>{JSON.stringify(response, null, 2)}</pre>
47 </div>
48 )}
49
50 {error && <div className="overflow-auto">❌ {String(error)}</div>}
51 </form>
52 );
53}
1'use client';
2import { useState, type FormEvent } from 'react';
3import { FormController } from 'vovk-client';
4import type { VovkReturnType } from 'vovk';
5
6export default function FormExample() {
7 const [response, setResponse] = useState<VovkReturnType<typeof FormController.createUser> | null>(null);
8 const [error, setError] = useState<Error | null>(null);
9 const [name, setName] = useState('');
10 const [email, setEmail] = useState('');
11 const [disableClientValidation, setDisableClientValidation] = useState(false);
12 const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
13 e.preventDefault();
14 try {
15 setResponse(
16 await FormController.createUser({
17 body: { name, email },
18 disableClientValidation,
19 })
20 );
21 setError(null);
22 } catch (e) {
23 setError(e as Error);
24 setResponse(null);
25 }
26 };
27
28 return (
29 <form onSubmit={onSubmit}>
30 <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
31 <input type="text" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
32 <label className="block mb-4">
33 <input
34 type="checkbox"
35 className="mr-2"
36 checked={disableClientValidation}
37 onChange={(e) => setDisableClientValidation(e.target.checked)}
38 />
39 Disable client-side validation
40 </label>
41 <button>Submit</button>
42
43 {response && (
44 <div className="text-left">
45 <h3>Response:</h3>
46 <pre>{JSON.stringify(response, null, 2)}</pre>
47 </div>
48 )}
49
50 {error && <div className="overflow-auto">❌ {String(error)}</div>}
51 </form>
52 );
53}
1'use client';
2import { useState, type FormEvent } from 'react';
3import { FormController } from 'vovk-client';
4import type { VovkReturnType } from 'vovk';
5
6export default function FormExample() {
7 const [response, setResponse] = useState<VovkReturnType<typeof FormController.createUser> | null>(null);
8 const [error, setError] = useState<Error | null>(null);
9 const [name, setName] = useState('');
10 const [email, setEmail] = useState('');
11 const [disableClientValidation, setDisableClientValidation] = useState(false);
12 const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
13 e.preventDefault();
14 try {
15 setResponse(
16 await FormController.createUser({
17 body: { name, email },
18 disableClientValidation,
19 })
20 );
21 setError(null);
22 } catch (e) {
23 setError(e as Error);
24 setResponse(null);
25 }
26 };
27
28 return (
29 <form onSubmit={onSubmit}>
30 <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
31 <input type="text" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />
32 <label className="block mb-4">
33 <input
34 type="checkbox"
35 className="mr-2"
36 checked={disableClientValidation}
37 onChange={(e) => setDisableClientValidation(e.target.checked)}
38 />
39 Disable client-side validation
40 </label>
41 <button>Submit</button>
42
43 {response && (
44 <div className="text-left">
45 <h3>Response:</h3>
46 <pre>{JSON.stringify(response, null, 2)}</pre>
47 </div>
48 )}
49
50 {error && <div className="overflow-auto">❌ {String(error)}</div>}
51 </form>
52 );
53}