TypeError after copying a working example, trying to read subscribe from undefined
I get the TypeError: Cannot read properties of undefined (reading 'subscribe') in my simple experiment.
I've copied the code from shadcn, but for some reason it does not work.
Below is my command component, and I can't see anything weird with it.
"use client";
import { type DialogProps } from "@radix-ui/react-dialog";
import { Command as CommandPrimitive } from "cmdk";
import { Search } from "lucide-react";
import * as React from "react";
import { cn } from "../@shadcn-lib";
import { Dialog, DialogContent } from "./dialog";
const Command = React.forwardRef<
React.ElementRef<typeof CommandPrimitive>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
>(({ className, ...props }, ref) => {
return (
<CommandPrimitive
ref={ref}
className={cn(
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
className,
)}
{...props}
/>
);
});
Command.displayName = CommandPrimitive.displayName;
const CommandDialog = ({ children, ...props }: DialogProps) => {
return (
<Dialog {...props}>
<DialogContent className="overflow-hidden p-0 shadow-lg">
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
{children}
</Command>
</DialogContent>
</Dialog>
);
};
const CommandInput = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Input>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
>(({ className, ...props }, ref) => (
// eslint-disable-next-line react/no-unknown-property
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
<CommandPrimitive.Input
ref={ref}
className={cn(
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
{...props}
/>
</div>
));
CommandInput.displayName = CommandPrimitive.Input.displayName;
const CommandList = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.List>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
>(({ className, ...props }, ref) => (
<CommandPrimitive.List
ref={ref}
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
{...props}
/>
));
CommandList.displayName = CommandPrimitive.List.displayName;
const CommandEmpty = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Empty>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
>((props, ref) => (
<CommandPrimitive.Empty
ref={ref}
className="py-6 text-center text-sm"
{...props}
/>
));
CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
const CommandGroup = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Group>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Group
ref={ref}
className={cn(
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
className,
)}
{...props}
/>
));
CommandGroup.displayName = CommandPrimitive.Group.displayName;
const CommandSeparator = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Separator
ref={ref}
className={cn("-mx-1 h-px bg-border", className)}
{...props}
/>
));
CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
const CommandItem = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
className,
)}
{...props}
/>
));
CommandItem.displayName = CommandPrimitive.Item.displayName;
const CommandShortcut = ({
className,
...props
}: React.HTMLAttributes<HTMLSpanElement>) => {
return (
<span
className={cn(
"ml-auto text-xs tracking-widest text-muted-foreground",
className,
)}
{...props}
/>
);
};
CommandShortcut.displayName = "CommandShortcut";
const CommandLoading = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Loading>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Loading>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Loading
ref={ref}
className={cn("px-2 py-1.5 text-center text-sm", className)}
{...props}
/>
));
CommandLoading.displayName = CommandPrimitive.Loading.displayName;
export {
Command,
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandLoading,
CommandSeparator,
CommandShortcut,
};
I then use it like so:
import { suggestAction } from "@domains/search/search-actions";
import {
Command,
CommandEmpty,
CommandGroup,
CommandItem,
CommandList,
} from "@repo/ui/command";
import { cn } from "@repo/ui/shadcn-lib";
import { useDebounce } from "@utils/helper-hooks";
import { SiteContext } from "@utils/service-types";
import { CommandLoading, Command as CommandPrimitive } from "cmdk";
import { LoaderCircle } from "lucide-react";
import {
KeyboardEventHandler,
useEffect,
useRef,
useState,
useTransition,
} from "react";
interface SuggestAutoCompleteProps {
onSubmit?: () => void;
className?: string;
siteContext: SiteContext;
}
export function SuggestAutoComplete({
onSubmit,
className,
siteContext,
}: SuggestAutoCompleteProps) {
const [open, setOpen] = useState(false);
const [isPending, startTransition] = useTransition();
const [items, setItems] = useState<{ value: string; label: string }[]>([]);
const [search, setSearch] = useState("");
const debouncedSearch = useDebounce(search, 300);
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (debouncedSearch) {
startTransition(async () => {
const data = await suggestAction(siteContext, debouncedSearch);
if (data.success) {
setItems(
data.data.map((d) => ({
label: d.name,
value: d.href ?? d.name,
})),
);
}
});
} else {
setItems([]);
}
}, [debouncedSearch, siteContext]);
const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {
if (event.key === "Escape") {
inputRef.current?.blur();
}
};
function handleSelect(currentValue: string) {
startTransition(async () => {
setSearch(currentValue);
inputRef.current?.blur();
onSubmit?.();
});
}
return (
<Command shouldFilter={false} className="overflow-visible">
<CommandPrimitive.Input
ref={inputRef}
placeholder="Search products"
value={search}
onInput={(e) => setSearch(e.currentTarget.value)}
onKeyDown={handleKeyDown}
onFocus={() => setOpen(true)}
onBlur={() => setOpen(false)}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"placeholder:font-light",
className,
)}
/>
<div className="relative">
{open && debouncedSearch ? (
<CommandList className="absolute top-1.5 z-50 w-full rounded-md border border-border bg-background">
{isPending ? (
<CommandLoading>
<LoaderCircle className="h-4 w-4 animate-spin text-muted-foreground" />
</CommandLoading>
) : (
<>
<CommandEmpty>No results.</CommandEmpty>
<CommandGroup>
{items.map((item, i) => {
const [first, rest] = item.label.split(/,(.+)/);
return (
<CommandItem
key={`${item.value}-${item.label}-${i}`}
value={item.value}
onSelect={handleSelect}
onMouseDown={(e) => {
e.preventDefault();
e.stopPropagation();
}}
className="flex gap-1 truncate items-baseline"
>
<span key={first}>{first}</span>{" "}
<span
key={rest}
className="truncate text-xs text-muted-foreground"
>
{rest}
</span>
</CommandItem>
);
})}
</CommandGroup>
</>
)}
</CommandList>
) : null}
</div>
</Command>
);
}
Nothing to fancy at all as I see it. Any known causes to the error I see and how to fix?
I had a very similar error, but mine was because I accidentally imported an icon called "Command". Try swapping out components of the shadcn lib for barebones cmdk components until something starts working or double check your imports.
bump
https://github.com/shadcn-ui/ui/issues/1939#issuecomment-1826720441 Hope this helps you
@bvincent1, you are my hero! After a couple of hours, your tip saved my day.