0

I used shadcn Select and react-hook-form. I'd like to use Zod to validate the values, however, when I click the submit button, the Zod object receives undefined values for all the FormFields. onSubmitSearch is the submit handle, and onSubmit={form.handleSubmit(onSubmitSearch)} doesn't work/run because the values are not valid according to Zod. So I changed the code from onSubmit={form.handleSubmit(onSubmitSearch)} into onSubmit={onSubmitSearch}, and now onSubmitSearch is running and I saw the error in const parsed = formSchema.parse({ ...e });. It receives undefined values. What could be causing the problem? I'd appreciate any help.

import React from "react";
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem
} from "../../../libs/shadcn/components/ui/select";
import { Skeleton } from "../../../libs/shadcn/components/ui/skeleton";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormMessage
} from "../../../libs/shadcn/components/ui/form";
import * as z from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "../../../libs/shadcn/components/ui/button";

const SearchSection = ({ query }) => {
  const { data: dropdownValuesData, isFetching, isSuccess } = query;

  const formSchema = z.object({
    property_type: z.string(),
    developer_id: z.string(),
    location: z.string()
  });

  const form = useForm({
    resolver: zodResolver(formSchema),
    defaultValues: {
      property_type: "",
      developer_id: "",
      location: ""
    }
  });

  const onSubmitSearch = e => {
    e.preventDefault();
    formSchema.parse({ ...e }); // error here
  };

  return (
    <Form {...form}>
      <form
        onSubmit={onSubmitSearch}
        className="mt-10 mb-8 flex flex-col md:flex-row justify-center md:space-x-3 w-fit max-w-fit mx-auto"
      >
        <div className="flex flex-col md:flex-row space-y-3 md:space-y-0 md:space-x-3 justify-evenly w-fit">
          <FormField
            control={form.control}
            name="property_type"
            render={({ field }) => (
              <FormItem>
                <Select
                  onValueChange={field.onChange}
                  defaultValue={field.value}
                >
                  <FormControl>
                    <SelectTrigger className="py-1 px-2 rounded-md min-w-24 w-56 md:w-40 text-xs font-medium h-7 self-center">
                      <SelectValue placeholder="Property" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent className="w-56 h-fit max-h-60 text-xs">
                    {isFetching ? (
                      <div className="flex space-x-2 place-content-center">
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                      </div>
                    ) : isSuccess && dropdownValuesData ? (
                      dropdownValuesData.data.property_types.map(item => (
                        <SelectItem value={item.id.toString()} key={item.id}>
                          {item.property_type_name}
                        </SelectItem>
                      ))
                    ) : (
                      <h2 className="mt-2 text-center">No data available.</h2>
                    )}
                  </SelectContent>
                </Select>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="Developer"
            render={({ field }) => (
              <FormItem>
                <Select
                  onValueChange={field.onChange}
                  defaultValue={field.value}
                >
                  <FormControl>
                    <SelectTrigger className="py-1 px-2 rounded-md min-w-24 w-56 md:w-40 text-xs font-medium h-7 self-center">
                      <SelectValue placeholder="Developer" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent className="w-56 h-fit max-h-60 text-xs">
                    {isFetching ? (
                      <div className="flex space-x-2 place-content-center">
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                      </div>
                    ) : isSuccess && dropdownValuesData ? (
                      dropdownValuesData.data.real_estate_developers.map(
                        item => (
                          <SelectItem value={item.id.toString()} key={item.id}>
                            {item.real_estate_developer_name}
                          </SelectItem>
                        )
                      )
                    ) : (
                      <h2 className="mt-2 text-center">No data available.</h2>
                    )}
                  </SelectContent>
                </Select>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="Location"
            render={({ field }) => (
              <FormItem>
                <Select
                  onValueChange={field.onChange}
                  defaultValue={field.value}
                >
                  <FormControl>
                    <SelectTrigger className="py-1 px-2 rounded-md min-w-24 w-56 md:w-40 text-xs font-medium h-7 self-center">
                      <SelectValue placeholder="Location" />
                    </SelectTrigger>
                  </FormControl>
                  <SelectContent className="w-56 h-fit max-h-60 text-xs">
                    {isFetching ? (
                      <div className="flex space-x-2 place-content-center">
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                        <Skeleton className="h-2 w-2 rounded-full bg-gray-500" />
                      </div>
                    ) : isSuccess && dropdownValuesData ? (
                      dropdownValuesData.data.cities_with_projects.map(
                        (item, key) => {
                          if (item != null) {
                            return (
                              <SelectItem value={item} key={key}>
                                {item}
                              </SelectItem>
                            );
                          } else null;
                        }
                      )
                    ) : (
                      <h2 className="mt-2 text-center">No data available.</h2>
                    )}
                  </SelectContent>
                </Select>
                <FormMessage />
              </FormItem>
            )}
          />
        </div>
        <div className="flex justify-center md:justify-start mt-3 md:mt-0 self-center w-fit">
          <Button
            type="submit"
            className="bg-[#009889] hover:bg-[#008577] active:bg-[#007065] text-white rounded-md py-1 px-4 h-7 w-fit font-medium text-xs"
          >
            Search
          </Button>
        </div>
      </form>
    </Form>
  );
};

export default SearchSection;

The error is this:

Unhandled Runtime Error ZodError: [   {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "property_type"
    ],
    "message": "Required"   },   {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "developer_id"
    ],
    "message": "Required"   },   {
    "code": "invalid_type",
    "expected": "string",
    "received": "undefined",
    "path": [
      "location"
    ],
    "message": "Required"   } ]

1 Answer 1

0

Found the problem. One or more of my FormField name does not match the schema.

const formSchema = z.object({
    property_type: z.string(),
    developer_id: z.string(),
    location: z.string()
  });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.