how to properly fetch values for form
Unanswered
American Chinchilla posted this in #help-forum
American ChinchillaOP
what is the proper way of getting data from database to display it in form, and then once form is submitted save those values in database again
a quick use case could be that you set your username to something, then when you get again to the change username form it already contains the username you set before so you can modify it
a quick use case could be that you set your username to something, then when you get again to the change username form it already contains the username you set before so you can modify it
6 Replies
American ChinchillaOP
im using react-hook-form and a prisma orm for database
Arboreal ant
I do a fetch request on the page component which runs server side, and pass that down to the client component form. With react-hook-form you can specify default values. Then once the submit is completed I invalidate the fetch request for the server side fetch, and trigger a router.refresh for the client component with the form so if you stay on the page with the form it has the latest values.
Asian paper wasp
High-level steps, assuming you are using App Router:
1. In the parent server component, query the DB using Prisma to get the username
2. Pass the username as a prop of the form component, which sets the sets the default value of the input field
3. Use React Hook Form as usual, except: create a server action that takes the new username and updates the DB accordingly. When calling
1. In the parent server component, query the DB using Prisma to get the username
2. Pass the username as a prop of the form component, which sets the sets the default value of the input field
3. Use React Hook Form as usual, except: create a server action that takes the new username and updates the DB accordingly. When calling
handleSubmit(), do so like handleSubmit(updateUsername), where updateUsername is a server action directly updating the DB@Asian paper wasp High-level steps, assuming you are using App Router:
1. In the parent server component, query the DB using Prisma to get the username
2. Pass the username as a prop of the form component, which sets the sets the default value of the input field
3. Use React Hook Form as usual, except: create a server action that takes the new username and updates the DB accordingly. When calling `handleSubmit()`, do so like `handleSubmit(updateUsername)`, where updateUsername is a server action directly updating the DB
American ChinchillaOP
the problem is, i kinda need to be on client side to know about what to query the database
ill maybe show some code i do have currently
i have a
for welcomeChannel it uses
app/dashboard/[guildId]/page.tsx that renders a <WelcomeForm />"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Textarea } from "./ui/textarea"
import ChannelSelect from "./form/ChannelSelect"
import { addData } from "@/lib/actions"
import { useCurrentGuild } from "@/app/contexts/CurrentGuildContext"
const FormSchema = z.object({
welcomeChannel: z.string(),
welcomeMessage: z.string().min(2),
})
export default function WelcomeForm() {
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
})
const { guild } = useCurrentGuild()
async function onSubmit(data: z.infer<typeof FormSchema>) {
await addData(guild.id, data)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<FormField
control={form.control}
name="welcomeChannel"
render={({ field }) => (
<FormItem>
<FormLabel>Welcome channel</FormLabel>
<ChannelSelect {...field} />
<FormDescription>
Select a channel where to send welcome message
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="welcomeMessage"
render={({ field }) => (
<FormItem>
<FormLabel>Welcome message</FormLabel>
<FormControl>
<Textarea
placeholder="Message"
className="resize-none"
{...field}
/>
</FormControl>
<FormDescription>
The message that will be sent to the welcome channel
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</form>
<Button type="submit">Save</Button>
</Form>
)
} this is this component, it has to be client side cause it uses context, that stores the current guild the dashboard is at (the guildId param in the link)for welcomeChannel it uses
<ChannelSelect /> which looks like this"use client"
import { useCurrentGuild } from "@/app/contexts/CurrentGuildContext"
import { FormControl } from "@/components/ui/form"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
export default async function ChannelSelect({
onChange,
}: {
onChange: (value: string) => void
}) {
const { channels } = useCurrentGuild()
const textChannels = channels.filter((channel) => channel.type === 0)
return (
<Select onValueChange={onChange} defaultValue={undefined}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Select a channel" />
</SelectTrigger>
</FormControl>
<SelectContent>
{textChannels.map(({ id, name }) => (
<SelectItem key={id} value={id}>
#{name}
</SelectItem>
))}
</SelectContent>
</Select>
)
} now i want to display the channel that was selected before if so in that select so using defaultValue prop, the problem comes how to get that from db