This package is designed to handle mutations in your solid-start app efficiently. It ensures type safety, input validation, and handles server errors and success states, providing a reliable and safe way to execute Solidjs Server Actions.
You can install this package via npm or yarn:
npm install solid-safe-action
# or
yarn add solid-safe-action
Here is an example of how to use solid-safe-action in a SolidJS application:
First, create a safe action:
'use server'
import { createSafeAction } from "solid-safe-action";
import { simulateDatabaseCall } from "~/lib/mock"; // mock db call
import { CreateForm } from "~/lib/schema"; // zod schema for validation
import { InputType, ReturnType } from "~/lib/types"; // type infer from zod schema and type of your action state
const handler = async (data: InputType): Promise<ReturnType> => {
const { title } = data;
let item;
try {
// Mock db call
item = await simulateDatabaseCall({ title})
} catch (error) {
return { error: 'Failed to create!' };
}
return { data: item };
};
export const createForm = createSafeAction(CreateForm, handler);
Define types based on the Zod schema:
import { z } from "zod";
export const CreateForm = z.object({
title: z.string({
required_error: "Title is required",
invalid_type_error: "Title is required"
}).min(4, { message: 'Title too short' }),
});
Define types based on the Zod schema:
import { z } from "zod";
import { ActionState } from "~/lib/create-safe-action";
import { CreateForm } from "./schema";//
export type InputType = z.infer<typeof CreateForm>;
export type ReturnType = ActionState<InputType, { title: string; }>;
Finally, use the useSafeAction hook to execute the action:
'use client'
import { useSafeAction } from "solid-safe-action";
import { createForm } from "~/actions/index;
const ExampleButton = () => {
const { execute, isLoading, } = useSafeAction(createForm, {
onSuccess: (data) => {
window.alert(`Success: ${JSON.stringify(data, null, 2)}`);
},
onError: (error) => {
window.alert("Error: " + error);
}
});
const onClick = (title: string) => {
execute({ title });
};
return (
<button disabled={isLoading()} onClick={() => onClick("Button")}>
Click to make a database call using server action
</button>
);
};
export default ExampleButton;