S
SolidJS•15mo ago
vik

How to array.filter Signal with array and pass down as Signal

I have a component:
export function ComboBox({
options,
selected,
setSelected,
}

// with
createEffect(() =>
setFilteredOptions(
options.filter((option) =>
option.label.toLowerCase().includes(searchTerm().toLowerCase())
)
)
);

// returns combox with div, ul, li...
export function ComboBox({
options,
selected,
setSelected,
}

// with
createEffect(() =>
setFilteredOptions(
options.filter((option) =>
option.label.toLowerCase().includes(searchTerm().toLowerCase())
)
)
);

// returns combox with div, ul, li...
That's how I call it
onMount(async () => {
const [categories, levels] = await Promise.all([
getCategories(locale) as Promise<Category[]>,
getLevels(locale) as Promise<Level[]>,
]);

setData({
categories,
levels,
});
});

return...
<ComboBox
options={categories().filter((c) => !c.parent) || []}
selected={selectedCategory}
setSelected={setSelectedCategory}
placeholder="Select a category"
/>
onMount(async () => {
const [categories, levels] = await Promise.all([
getCategories(locale) as Promise<Category[]>,
getLevels(locale) as Promise<Level[]>,
]);

setData({
categories,
levels,
});
});

return...
<ComboBox
options={categories().filter((c) => !c.parent) || []}
selected={selectedCategory}
setSelected={setSelectedCategory}
placeholder="Select a category"
/>
This was working with solidstart and routedata/createServerDta$, but now I have to use solidjs. I think it was working, because of ssr I think my Combox createEffect is never been called because options that I hand over is not a Signal anymore. So what would be an optimal strategy?
10 Replies
thetarnav
thetarnav•15mo ago
use createMemo for the filtered array
vik
vikOP•15mo ago
Sure! Is that the most elegant way?
thetarnav
thetarnav•15mo ago
probably tbh I'm still trying to understand whats the issue effects definitely won't be called on the server because they are not meant to be used for state syncing
vik
vikOP•15mo ago
I know, but then I never really checked if the effect was working and it was probably not crucial for current state of progress. So CombBox is a component, I would like to use it for different option[] kinds. I am not so sure about React anymore, I think would just rerender that complete ComboBox, on filter, so that might have worked in react?! But again I am not sure. Finding my way back to think reactive, think solidjs.
thetarnav
thetarnav•15mo ago
idiomatic solid might be very similar to idiomatic react but in react "just calling setState" will also kinda work, when here you always have to think about how to express the state with signals and memos Is replacing effect with a memo solving the problem? or is there something more?
vik
vikOP•15mo ago
It works! thanks. Too easy 🙂
const categoryOptions = createMemo(() =>
data().categories.filter((c) => !c.parent)
);
<ComboBox
options={categoryOptions}
selected={selectedCategory}
setSelected={setSelectedCategory}
placeholder="Select a category"
/>
const categoryOptions = createMemo(() =>
data().categories.filter((c) => !c.parent)
);
<ComboBox
options={categoryOptions}
selected={selectedCategory}
setSelected={setSelectedCategory}
placeholder="Select a category"
/>
thetarnav
thetarnav•15mo ago
ah ok I was taking about the other effect here you could just add () => before the prevoius expression and it would also work if you destructure props then you have to pass them as functions for lazy access
vik
vikOP•15mo ago
I understand. Haven't thought about createMemo inside Combobox. Sure, it would create the reactivity from the options by explicitly observing it. Actually
function ComboBox({
options,
selected,
setSelected,
}

const optionsMemo = createMemo(() => options);

// consume optionsMemo()
// not working
function ComboBox({
options,
selected,
setSelected,
}

const optionsMemo = createMemo(() => options);

// consume optionsMemo()
// not working
But <ComBoxy options={()=>categories.filter()}> works. (obviously i have to adjust ComboBox and usage of options)
M7
M7•15mo ago
cos "options" is a getter? i.e you should call it like const optionsMemo = createMemo(() => options()); i guess..
vik
vikOP•15mo ago
I solved this for now and understood a bit better reactivity of solidjs with help of thetarnav. Last comment showed what would not work, when option is an array, but not a function or Accessor. This thread shows shows a few approaches I have tried out. Finally I am choosing comobobox prop option to be a function. If I just pass down an array it won't work, because of lazy load feature of solidjs.
Want results from more Discord servers?
Add your server