Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12111

Unhandled Runtime Error TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

$
0
0

I am making a multiselect component in Next.js and I am using states and setting states. However, this error occurs:

enter image description here

whenever I click this:

enter image description here

This is the code of MultiSelect.tsx:

import { useState } from "react";import {  Command,  CommandDialog,  CommandEmpty,  CommandGroup,  CommandInput,  CommandItem,  CommandList,  CommandSeparator,  CommandShortcut,} from "@/components/ui/command";interface MultiSelectProps {  placeholder: string  collections: CollectionType[]  value: string[]  onChange: (value: string) => void  onRemove: (value: string) => void}const MultiSelect: React.FC<MultiSelectProps> = ({  placeholder,  collections,  value,  onChange,  onRemove,}) => {  const [inputValue, setInputValue] = useState("");  const [open, setOpen] = useState(false);  return (<Command className="overflow-visible bg-white"><CommandInput        placeholder={placeholder}        value={inputValue}        onValueChange={setInputValue}        onBlur={() => setOpen(false)}        onFocus={() => setOpen(true)}      /><div className="relative mt-2">        {open && (<CommandGroup className="absolute w-full z-10 top-0 overflow-auto border rounded-md shadow-md">            {collections.map((collection) => (<CommandItem key={collection._id}>{collection.title}</CommandItem>            ))}</CommandGroup>        )}</div></Command>  );};export default MultiSelect;

and here is the code from the ProductForm.tsx:

"use client";import { zodResolver } from "@hookform/resolvers/zod";import { useForm } from "react-hook-form";import { Separator } from "../ui/separator";import { z } from "zod";import { Button } from "@/components/ui/button";import {  Form,  FormControl,  FormDescription,  FormField,  FormItem,  FormLabel,  FormMessage,} from "@/components/ui/form";import { Input } from "@/components/ui/input";import { Textarea } from "../ui/textarea";import ImageUpload from "../custom ui/ImageUpload";import { useParams, useRouter } from "next/navigation";import { useEffect, useState } from "react";import toast from "react-hot-toast";import Delete from "../custom ui/Delete";import MultiText from "../custom ui/MultiText";import MultiSelect from "../custom ui/MultiSelect";const formSchema = z.object({  title: z.string().min(2).max(20),  description: z.string().min(2).max(500).trim(),  media: z.array(z.string()),  category: z.string(),  collections: z.array(z.string()),  tags: z.array(z.string()),  size: z.array(z.string()),  colors: z.array(z.string()),  price: z.coerce.number().min(0.1),  expense: z.coerce.number().min(0.1),});interface ProductFormProps {  initialData?: ProductType | null; // Must have ? to make it optional}const ProductForm: React.FC<ProductFormProps> = ({ initialData }) => {  const router = useRouter();  //const params = useParams();  const [loading, setLoading] = useState(false);  const [collections, setCollections] = useState<CollectionType[]>([]);  const getCollections = async () => {    try{      setLoading(true)      const res = await fetch("/api/collections", {        method: "GET",      })      const data = await res.json()      setCollections(data)      setLoading(false)    }catch(err) {      console.log("[collections_GET]", err)      toast.error("Something went wrong. Please try again.")    }  }  useEffect(() => {    getCollections()  }, [])  // 1. Define your form.  const form = useForm<z.infer<typeof formSchema>>({    resolver: zodResolver(formSchema),    defaultValues: initialData      ? initialData      : {          title: "",          description: "",          media: [],          category: "",          collections: [],          tags: [],          sizes: [],          colors: [],          price: 0.1,          expense: 0.1,        },  });  const handleKeyPress = (    e:      | React.KeyboardEvent<HTMLInputElement>      | React.KeyboardEvent<HTMLTextAreaElement>  ) => {    if (e.key === "Enter") {      e.preventDefault();    }  };  // 2. Define a submit handler.  const onSubmit = async (values: z.infer<typeof formSchema>) => {    // Do something with the form values.    // ✅ This will be type-safe and validated.    //console.log(values)    try {      setLoading(true);      const url = initialData        ? `/api/products/${initialData._id}`        : "/api/products";      const res = await fetch(url, {        method: "POST",        body: JSON.stringify(values),      });      if (res.ok) {        setLoading(false);        toast.success(`Product ${initialData ? "updated" : "created"}.`);        window.location.href = "/products";        router.push("/products");      }    } catch (err) {      console.log("[products_POST]", err);      toast.error("Something went wrong. Please try again.");    }  };  return (<div className="p-10">      {initialData ? (<div className="flex items-center justify-between"><p className="text-heading2-bold">Edit Product</p><Delete id={initialData._id} /></div>      ) : (<p className="text-heading2-bold">Create Product</p>      )}<Separator className="bg-grey-1 my-4 mb-7" /><Form {...form}><form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8"><FormField            control={form.control}            name="title"            render={({ field }) => (<FormItem><FormLabel>Title</FormLabel><FormControl><Input                    placeholder="Title"                    {...field}                    onKeyDown={handleKeyPress}                  /></FormControl><FormDescription>The title of the product.</FormDescription><FormMessage /></FormItem>            )}          /><FormField            control={form.control}            name="description"            render={({ field }) => (<FormItem><FormLabel>Description</FormLabel><FormControl><Textarea                    placeholder="Description"                    {...field}                    rows={5}                    onKeyDown={handleKeyPress}                  /></FormControl><FormDescription>                  The description of the product.</FormDescription><FormMessage /></FormItem>            )}          /><FormField            control={form.control}            name="media"            render={({ field }) => (<FormItem><FormLabel>Image</FormLabel><FormControl><ImageUpload                    value={field.value}                    onChange={(url) => field.onChange([...field.value, url])}                    onRemove={(url) =>                      field.onChange([                        ...field.value.filter((image) => image !== url),                      ])                    }                  /></FormControl><FormDescription>The image of the product.</FormDescription><FormMessage /></FormItem>            )}          /><div className="md: grid md:grid-cols-3 md:gap-8"><FormField              control={form.control}              name="price"              render={({ field }) => (<FormItem><FormLabel>Price ($)</FormLabel><FormControl><Input                      type="number"                      placeholder="Price"                      {...field}                      onKeyDown={handleKeyPress}                    /></FormControl><FormDescription>The price of the product.</FormDescription><FormMessage /></FormItem>              )}            /><FormField              control={form.control}              name="expense"              render={({ field }) => (<FormItem><FormLabel>Expense ($)</FormLabel><FormControl><Input                      type="number"                      placeholder="Expense"                      {...field}                      onKeyDown={handleKeyPress}                    /></FormControl><FormDescription>The expense of the product.</FormDescription><FormMessage /></FormItem>              )}            /><FormField              control={form.control}              name="category"              render={({ field }) => (<FormItem><FormLabel>Category</FormLabel><FormControl><Input                      placeholder="Category"                      {...field}                      onKeyDown={handleKeyPress}                    /></FormControl><FormMessage className="text-red-1" /></FormItem>              )}            /><FormField              control={form.control}              name="tags"              render={({ field }) => (<FormItem><FormLabel>Tags</FormLabel><FormControl><MultiText                      placeholder="Tags"                      value={field.value}                      onChange={(tag) => field.onChange([...field.value, tag])}                      onRemove={(tagToRemove) =>                        field.onChange([                          ...field.value.filter((tag) => tag !== tagToRemove),                        ])                      }                    /></FormControl><FormMessage className="text-red-1" /></FormItem>              )}            /><FormField              control={form.control}              name="collections"              render={({ field }) => (<FormItem><FormLabel>Collections</FormLabel><FormControl><MultiSelect                      placeholder="Collections"                      collections={collections}                      value={field.value}                      onChange={(_id) => field.onChange([...field.value, _id])}                      onRemove={(idToRemove) =>                        field.onChange([                          ...field.value.filter((collectionId) => collectionId !== idToRemove),                        ])                      }                    /></FormControl><FormMessage className="text-red-1" /></FormItem>              )}            /></div><div className="flex gap-10"><Button type="submit" className="bg-blue-1 text-white">              Submit</Button><Button              type="button"              onClick={() => router.push("/collections")}              className="bg-blue-1 text-white">              Discard</Button></div></form></Form></div>  );};export default ProductForm;

When I click the multiselect component, I am expecting it to show the current collection list.


Viewing all articles
Browse latest Browse all 12111

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>