Snippets Collections
const express = require("express");
const { z } = require("zod");

const app = express();

app.use(express.json());

const LoginSchema = z.object({
  // In this example we will only validate the request body.
  body: z.object({
    // email should be valid and non-empty
    email: z.string().email(),
    // password should be at least 6 characters
    password: z.string().min(6),
  }),
});

const validate = (schema) => (req, res, next) => {
  try {
    schema.parse({
      body: req.body,
      query: req.query,
      params: req.params,
    });

    next();
  } catch (err) {
    return res.status(400).send(err.errors);
  }
};

app.post("/login", validate(LoginSchema), (req, res) => {
  return res.json({ ...req.body });
});

app.listen(1337, () => console.log(`> Ready on http://localhost:${1337}`));
import { zodResolver } from "@hookform/resolvers/zod";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";

const signUpSchema = z
  .object({
    email: z
      .string()
      .nonempty("email is required")
      .email("Invalid email address"),
    password: z.string().min(8, "Password must be at least 8 characters"),
    confirmPassword: z.string(),
  })
  // we can use zod to validate using refine method
  .refine((data) => data.password === data.confirmPassword, {
    message: "Passwords do not match",
    path: ["confirmPassword"], // it will show error in confirmPassword field
  });

type ISignUpSchema = z.infer<typeof signUpSchema>; // create type from schema

const ReactHookFormWithZod = () => {
  const [show, setShow] = useState(false);
  const [show1, setShow1] = useState(false);
  const { register, handleSubmit, formState, reset } = useForm<ISignUpSchema>({
    resolver: zodResolver(signUpSchema), //tell which schema to resolve
  });
  const { errors, isSubmitting } = formState;

  const onSubmit = async (data: ISignUpSchema) => {
    console.log(data);
    //-------send data to server----------//
    await new Promise((resolve) => setTimeout(resolve, 1000));
    //------
    reset(); // clear form
  };
  return (
    <form
      onSubmit={handleSubmit(onSubmit)}
      className="flex flex-col gap-y-4 [&>div>input]:w-full"
    >
      <label className="-mb-3 text-sm text-gray-500" htmlFor="email">
        email
      </label>
      <div className="">
        <input
          {...register("email")}
          type="text"
          placeholder="email"
          className="rounded border px-4 py-2"
        />
        {
          // granular show errors
          errors.email && (
            <p className="text-sm text-red-500">{`${errors.email.message}`}</p>
          )
        }
      </div>
      <label className="-mb-3 text-sm text-gray-500" htmlFor="password">
        password
      </label>
      <div className="relative ">
        <input
          {...register("password")}
          type={show ? "text" : "password"}
          id="password"
          placeholder="password"
          className=" block rounded border py-2 pl-2 pr-12"
        ></input>
        <p
          className="absolute  right-2 top-0 block cursor-pointer select-none py-2 "
          onClick={() => setShow((show) => !show)}
        >
          👁️
        </p>
        {
          // granular show errors
          errors.password && (
            <p className="text-sm text-red-500">{`${errors.password.message}`}</p>
          )
        }
      </div>
      <label className="-mb-3 text-sm text-gray-500" htmlFor="confirmPassword ">
        confirm password
      </label>
      <div className="relative">
        <input
          {...register("confirmPassword")}
          id="confirmPassword"
          type={show1 ? "text" : "password"}
          placeholder="confirm password"
          className="rounded border py-2 pl-2 pr-10 "
        />
        <p
          className="absolute  right-2 top-0 block cursor-pointer select-none py-2 "
          onClick={() => setShow1((show) => !show)}
        >
          👁️
        </p>
        {
          // granular show errors
          errors.confirmPassword && (
            <p className="text-sm text-red-500">{`${errors.confirmPassword.message}`}</p>
          )
        }
      </div>

      <button
        type="submit"
        className="rounded bg-blue-500 py-2 text-white disabled:cursor-no-drop disabled:bg-gray-500"
        disabled={isSubmitting}
      >
        {isSubmitting ? "loading..." : "Submit"}
      </button>
    </form>
  );
};

export default ReactHookFormWithZod;
star

Sun Nov 05 2023 04:28:47 GMT+0000 (Coordinated Universal Time) https://www.imadatyat.me/guides/schema-validation-with-zod-and-expressjs

#javascript #express #zod #backend

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension