#how to populate form with default values?

16 messages · Page 1 of 1 (latest)

hidden oriole
#

hi team, when i have the following code, it doesnt populate my form with current values in the db because it's undefined for 3 seconds before the values show up.
by then, the defaultValues in the useForm have already been populated with empty values. does anyone know how can i fix it?
in other words, how can i call the useForm hook after it finishes loading? thanks!

const myShop = useQuery(api.myShopFuncs.getmyShopProfile, {
  clerkOrganizationId: orgId || "",
})

const createMyShopProfileMutation = useMutation(
  api.myShopFuncs.createMyShopProfile
)

const form = useForm<MyShopFormValues>({
  resolver: zodResolver(myShopSchema),
  defaultValues: {
    size: myShop?.size || "",
    areas: myShop?.areas || [],
    features: myShop?.features || [],
  },
  reValidateMode: "onBlur",
})
sage knot
#

Guessing you're using react-hook-form, they give this approach for async default values in the docs:

// set default value async
useForm({
  defaultValues: async () => fetch('/api-endpoint');
})
#

In your case you could make a promise that resolves when your query comes back

#

Hmm trying to think of how to do that idiomatically in this case

#

I think I'd wrap your form along with useForm into a separate component, and skip rendering until myShop !== undefined.

#

Convex team may have a better idea 🙂

normal slate
#

if you do const convex = useConvex(); then you can call convex.query(api.myShopFuncs.getMyShopProfile) which returns a promise. Then you can use @sage knot 's async defaultValues idea to await the promises and get the values

hidden oriole
#

wow thanks! looks like it's my lack of familiarity with the react use-form hook after all. anyway, i tried doing it but still running into undefined when it first renders. i should probably move the useQuery one level up the component. do y'all have better suggestion?

defaultValues: async () => {
  const myShopProfile = await convex.query(
    api.myShopFuncs.getmyShopProfile,
    {
      clerkOrganizationId: orgId || "",
    }
  )
  console.log(myShopProfile) // undefined
  return {
    size: myShopProfile?.size || "",
    areas: myShopProfile?.areas || [],
    features: myShopProfile?.features || [],
  }
},
acoustic osprey
#

That's pretty weird,

const result = await convex.query(
  api.anyApiFunction,
  anyArgs
)

should never return undefined. It could possibly return null if the query function returns undefined.

#

Could you try changing the console.log() to something like

console.log("myShopProfile:", myShopProfile);

just to confirm?

hidden oriole
#

ahh you're right. my bad, it's because the anyArgs passed into the function is undefined too... 😂

#

looks like the only way i can get around this is to wait for the values to show up before im able to pass them

#

thanks all!! 🙂

hidden oriole
#

on a side note, is it possible do sth like Awaited<ReturnType<api.anyApiFunction>>?

acoustic osprey
#

Totally, this almost works as you've written it