Set.prototype.has() returns false even when element is present
I learning React.js, and would like to implement filter functionality based on the checkboxes selected. I am referring to this solution >> https://codepen.io/trezy/pen/GROLXqo
So far, I have the following implementation:
Code for filter function:
const [state, setState] = useState({
products: cspaces,
filters: new Set(),
})
const handleFilterChange = useCallback(event => {
setState(previousState => {
let filters = new Set(previousState.filters)
let products = cspaces
.....
products = products.filter(product => {
return filters.has(
product.attributes.propertySubType.split(" ").forEach(element => {
if((element.match(/Shop|Office|Showroom/))!=null)
console.log("element ", element)
return element
....
console.log("products ",products)
}
return {
filters,
products,
}
})
}, [setState])
The checkboxes:
...
{data.propertytype.items.map((tag, index) => (
<li key={tag.value}>
<Form.Check
type="checkbox"
value={tag.label}
onChange={handleFilterChange}
/>
</li>
...
And my component using the filtered data,
...
{state.products.map((filteredListItems, id) => (
<Col
key={id}
sm="6"
lg="4"
className="mb-5 hover-animate"
>
<CardCspace data={filteredListItems} />
</Col>
))}
...
cspaces is holding the data fetched from API. The value of state.products returned by filtering function is always empty. I would like to match with the categories "Shop", "Office", or "Showroom" which are displayed in checkboxes.
Sample console output:22 Replies
forEach returns nothing. so that would make sense
so you're basically doing
set.has(undefined)
Thank you for your reply @ghardin137 . I have edited my code and am using .filter() in place of forEach(), does this help? How should I proceed?
what are the values in the set/
because filter will return an array
and it'll be a new reference
so i'm guessing that's probably not what you want
As u can see in the sample console output I posted, I have chosen "Shop, it can also have multiple values
so the set contains strings
and you want to only get the products that have one of the values in the set in
propertySubType
?
or all of the values in the set/I would like to return the products which have the filters set values in ...propertySubType, which is a string. Hence I have split it on space
you don't necessarily have to split it
you want it to have one of the values in filters or ALL of the values in filters?
All the values
like is filters an AND or an OR
any reason you're using a set over an array here?
Well, I am using already-implemented solutions in my code
not sure what that means exactly.
this would be simpler if filters was an array instead of a set
In that case, I will use an array and check if that helps. Thank you
i mean it won't solve your problem
you'd need a combination of array.prototype.every and array.prototype.includes here
and change your logic
if it were an array you could do like
and that would tell you if all of the filters are in the propertySubType
I will try to implement this. Could you please tell me how to properly add and remove items from the filters array?
if (event.target.checked) {
filters.push(event.target.value)
} else {
var index = filters.indexOf(event.target.value)
filters.splice(index, 1)
}
Im doing this
i would use filter rather than splice
you generally want your updates to be immutable
so you'd do like and
Though I am using every on filters, if i select multiple filters the products array is empty
do you have any products that have both of those filters?
a product that's both Shop and Showroom?
No not both of them at once, but separately..like I would like sites that are showrooms and sites that are shops to be displayed.
so it's an or not an and
Yeah that would be correct
Solution
Thanks a ton! It works