From c7983fafaaabf25e9f485ede80048f716d6b0109 Mon Sep 17 00:00:00 2001 From: zerone0x Date: Tue, 13 Jan 2026 15:53:02 +0800 Subject: [PATCH] fix(ui): handle async items function in useFilteredList hook When props.items is an async function, calling it in the source function without arguments returns a Promise. This Promise was then passed directly to the fetcher as 'items', but since Promise is truthy, the fallback `items ?? await props.items(needle)` didn't trigger, causing the code to try iterating over a Promise object instead of an array. This fix checks if items is a Promise or not an array, and if so, properly calls the async function with the filter parameter. Fixes #8148 Co-Authored-By: Claude --- packages/ui/src/hooks/use-filtered-list.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/hooks/use-filtered-list.tsx b/packages/ui/src/hooks/use-filtered-list.tsx index b6bd7d5c6c0..db2fee5482b 100644 --- a/packages/ui/src/hooks/use-filtered-list.tsx +++ b/packages/ui/src/hooks/use-filtered-list.tsx @@ -24,6 +24,7 @@ export function useFilteredList(props: FilteredListProps) { const [grouped, { refetch }] = createResource( () => { // When items is a function (not async filter function), call it to track changes + // Don't call async functions here - they'll be called in the fetcher with the filter const itemsValue = typeof props.items === "function" ? (props.items as () => T[])() // Call synchronous function to track it @@ -36,7 +37,13 @@ export function useFilteredList(props: FilteredListProps) { }, async ({ filter, items }) => { const needle = filter?.toLowerCase() - const all = (items ?? (await (props.items as (filter: string) => T[] | Promise)(needle))) || [] + // Handle case where items is a Promise (from async function called without filter) + // In that case, we need to call the function again with the proper filter + const resolvedItems = + items instanceof Promise || !Array.isArray(items) + ? await (props.items as (filter: string) => T[] | Promise)(needle ?? "") + : items + const all = resolvedItems || [] const result = pipe( all, (x) => {