properly query database for form data
Answered
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, im using react-hook-form with shadcnui and a prisma orm for database
the problem is, the id i need for sql query is on client side stored in context (the
i have a
for welcomeChannel it uses
the problem is, the id i need for sql query is on client side stored in context (the
guildId from link)i have a
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 dbAnswered by jason
If your page component is on a dynamic route, technically in the RSC page you should be able to pull the
For example:
Hope this helps.
guildId For example:
export default function Page({ params }: { params: { guildId: string } }) {
// ...Hope this helps.
9 Replies
Have you tried fetching db data on your page and then prop drilling into the components as needed?
Within your
After saving to the database you can add
Within your
addData server action, I'm assuming that you are saving to the database?After saving to the database you can add
revalidatePath('/your-route') so purge cached data for that route.@jason Have you tried fetching db data on your page and then prop drilling into the components as needed?
Within your `addData` server action, I'm assuming that you are saving to the database?
After saving to the database you can add `revalidatePath('/your-route')` so purge cached data for that route.
American ChinchillaOP
Well i can try doing that
Yea it adds to db
Yea it adds to db
French Angora
I have a similar question. I want to display the data from the db inside the Input under FormControl, and the user should be able to click on the input and edit it, then, that input should be saved to the DB.
Do you have any idea how I can do this?
I tried using useState, and defaultValue in Input, but it does not work with the {...field} in Input...
Do you have any idea how I can do this?
I tried using useState, and defaultValue in Input, but it does not work with the {...field} in Input...
@jason Have you tried fetching db data on your page and then prop drilling into the components as needed?
Within your `addData` server action, I'm assuming that you are saving to the database?
After saving to the database you can add `revalidatePath('/your-route')` so purge cached data for that route.
American ChinchillaOP
so i tried what you suggested and it wont work at least i think it wont since to query the database i need info from client side
what i mean is to know what info to get from database i need to know on what route user is (the
guildId param in url especially)i have that in Context but to use Context i need to be on client side too
If your page component is on a dynamic route, technically in the RSC page you should be able to pull the
For example:
Hope this helps.
guildId For example:
export default function Page({ params }: { params: { guildId: string } }) {
// ...Hope this helps.
Answer
Hey if that worked for you, would you mind marking the solution?