Skip to content

Commit

Permalink
feat(example): add nested schema example
Browse files Browse the repository at this point in the history
  • Loading branch information
TheEdoRan committed Jan 30, 2024
1 parent b1a0077 commit e4a0346
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
13 changes: 13 additions & 0 deletions packages/example-app/src/app/nested-schema/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import ShopForm from "./shop-form";

export const metadata = {
title: "Nested schema",
};

export default function NestedSchemaPage() {
return (
<>
<ShopForm />
</>
);
}
75 changes: 75 additions & 0 deletions packages/example-app/src/app/nested-schema/shop-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"use server";

import { action } from "@/lib/safe-action";
import { z } from "zod";

const input = z
.object({
user: z.object({
id: z.string().uuid(),
}),
product: z.object({
deeplyNested: z.object({
id: z.string().uuid(),
}),
}),
})
.superRefine((_, ctx) => {
// Randomly generate validation error for root.
if (Math.random() > 0.5) {
ctx.addIssue({
code: "custom",
message: "Parent schema error",
});
}

// Randomly generate validation error for user object.
if (Math.random() > 0.5) {
ctx.addIssue({
code: "custom",
path: ["user"],
message: "Parent user error",
});
ctx.addIssue({
code: "custom",
path: ["user"],
message: "Parent user error 2",
});
}

// Randomly generate validation error for user id.
if (Math.random() > 0.5) {
ctx.addIssue({
code: "custom",
path: ["user", "id"],
message: "Another bad user id error",
});
}

// Randomly generate validation errors for product object.
if (Math.random() > 0.5) {
ctx.addIssue({
code: "custom",
path: ["product"],
message: "Parent product error",
});

ctx.addIssue({
code: "custom",
path: ["product", "deeplyNested"],
message: "Deeply nested product error",
});

ctx.addIssue({
code: "custom",
path: ["product", "deeplyNested", "id"],
message: "Product not found in the store",
});
}
});

export const buyProduct = action(input, async () => {
return {
success: true,
};
});
38 changes: 38 additions & 0 deletions packages/example-app/src/app/nested-schema/shop-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";

import { useState } from "react";
import { buyProduct } from "./shop-action";

const ShopForm = () => {
const [result, setResult] = useState(
"fill in form and click on the log in button"
);

return (
<>
<form
onSubmit={async (e) => {
e.preventDefault();

// Change one of these two to generate validation errors.
const userId = crypto.randomUUID();
const productId = crypto.randomUUID();

const res = await buyProduct({
user: { id: userId },
product: { deeplyNested: { id: productId } },
}); // this is the typesafe action called from client

setResult(JSON.stringify(res, null, 1));
}}>
<button type="submit">Buy product</button>
</form>
<div id="result-container">
<div>Action result:</div>
<pre className="result">{result}</pre>
</div>
</>
);
};

export default ShopForm;

0 comments on commit e4a0346

Please sign in to comment.