R
Reactiflux

⛄ Snowberb ⛄ – 12-56 May 26

⛄ Snowberb ⛄ – 12-56 May 26

S⛄Snowberb⛄5/26/2022
Im trying to do a multi-filter function on React, and I'm really stuck. I have diverse filters:
bookie: string[],
ganancia: { min: number, max: number },
completed: boolean,
event_date: 'ASC' | 'DESC'
bookie: string[],
ganancia: { min: number, max: number },
completed: boolean,
event_date: 'ASC' | 'DESC'
and I also have a lot of objects with those properties and more, called bonuses: IBonus[] My objective is that I have to apply all these filters to the bonuses object at once, depending on what the user selects, for example, bookies could be bet365, Sportium etc, ganancia could have a min of 20€ and a max of 100€ etc. How can I do this?
<div className="flex flex-col gap-y-3">
Casas:
{houses.map((house) => (
<button key={house} onClick={() => filterBonuses('bookie', house)}>
{house}
</button>
))}
</div>
<div className="flex flex-col gap-y-3">
Casas:
{houses.map((house) => (
<button key={house} onClick={() => filterBonuses('bookie', house)}>
{house}
</button>
))}
</div>
const filterBonuses = (filterType: keyof IBonus, option: string | number | boolean) => {
const newItems = bonuses.filter((bonus) => bonus[filterType] === option)
setFilteredItems(newItems)
}
const filterBonuses = (filterType: keyof IBonus, option: string | number | boolean) => {
const newItems = bonuses.filter((bonus) => bonus[filterType] === option)
setFilteredItems(newItems)
}
I could only achieve 1 filter at a time, I have no idea how I can chain all of them
SS3BAS5/26/2022
You don't chain the filters You could, but it's not necessary Rather, compose the predicates That is to say, you have a function which will take one of the filters and the object and returns true or false (this is the predicate) Create one such a predicate for every filter And then you can use all of these predicates in the .filter function, so only the objects for which true will be returned for all of the predicates will be kept
S⛄Snowberb⛄5/26/2022
could you explain this one more in depth please?
SS3BAS5/26/2022
Can you send the interface IBonus
S⛄Snowberb⛄5/26/2022
export interface IBonus {
id: string
titulo: string
tipo_de_bono: string
tipo_de_oferta: string
cuota_minima: number
cuota_maxima: number
fecha_evento: string
evento: string
condiciones: string
resumen: string
recompensa: string
bookie: string
ganancia: number
fecha_inicio: string
fecha_fin: string
invitacion: boolean
completado: boolean
tipo_de_juego?: string
juego?: string
}
export interface IBonus {
id: string
titulo: string
tipo_de_bono: string
tipo_de_oferta: string
cuota_minima: number
cuota_maxima: number
fecha_evento: string
evento: string
condiciones: string
resumen: string
recompensa: string
bookie: string
ganancia: number
fecha_inicio: string
fecha_fin: string
invitacion: boolean
completado: boolean
tipo_de_juego?: string
juego?: string
}
S⛄Snowberb⛄5/26/2022
This is the type of filter im talking about btw (styling not finished)
SS3BAS5/26/2022
Imagine the state is
ganacia = { min: 1, max: 10 }
completed = false
ganacia = { min: 1, max: 10 }
completed = false
then you can create a predicate for each
const ganaciaP = (ganaciaState: { min: number, max: number}, obj: IBonus) => obj.ganaciaState>= min && obj.ganaciaState<= max
const completedP = (completedState: boolean, obj: IBonus) => obj.completado === completedState
const ganaciaP = (ganaciaState: { min: number, max: number}, obj: IBonus) => obj.ganaciaState>= min && obj.ganaciaState<= max
const completedP = (completedState: boolean, obj: IBonus) => obj.completado === completedState
then use these predicates as such
bonuses.filter(bonus => ganaciaP(ganacia, bonus) && completedP(completed, bonus))
bonuses.filter(bonus => ganaciaP(ganacia, bonus) && completedP(completed, bonus))
And you can AND (&&) all of these predicates for every filter you have in there Be aware that if you have a filter that can be unselected / hold no value that the predicate should return true for those cases as well
S⛄Snowberb⛄5/26/2022
This way It would work only after hitting a button like "Apply filters"? Would it be a lot more complex to filter bonuses every time a user selects a filter?
SS3BAS5/26/2022
That depends on when you choose to update the state, this part is filtering the state once the filters have been selected
S⛄Snowberb⛄5/26/2022
mhm
SS3BAS5/26/2022
Complex in terms of what?
S⛄Snowberb⛄5/26/2022
difficulty
SS3BAS5/26/2022
No it is not, it does not change the piece of code Im suggesting That's about when you update the state You can choose to update the state as the user clicks and updates each individual filter (controlled components) or you choose to only sync the state once the user clicks the button "apply filter"
S⛄Snowberb⛄5/26/2022
waht im trying to say is that if you select for example betfair365 then in bonuses would only remain that house and if I deselect that filter i'd have no way of retrieving the other objects
SS3BAS5/26/2022
Don't update the state of bonuses
S⛄Snowberb⛄5/26/2022
I make a copy of it?
SS3BAS5/26/2022
You don't even have to Just filter the bonuses state bonuses will always have all the bonuses
S⛄Snowberb⛄5/26/2022
oh I get it
SS3BAS5/26/2022
There is no need to overwrite that state you just lose information that way
S⛄Snowberb⛄5/26/2022
true true okay let me try this thank you so much sebas
SS3BAS5/26/2022
And what you're supposed to do is deriving the filtered view for your state npnp
S⛄Snowberb⛄5/26/2022
you have no idea how many times you helped me in this server 🤣 how do I print the array? If in my component
<BonusList
currentItems={bonuses}
/>
<BonusList
currentItems={bonuses}
/>
I'd have to make a copy of bonuses dont I? :/
SS3BAS5/26/2022
No, .filter will create a new array Use that array
<BonusList
currentItems={bonuses.filter(bonus => predicate1(state, bonus) && ....)}
/>
<BonusList
currentItems={bonuses.filter(bonus => predicate1(state, bonus) && ....)}
/>
S⛄Snowberb⛄5/26/2022
and last thing, what if I have the list paginated like this?
useEffect(() => {
// Loading items from {currentOffset} to {endOffset}
const endOffset = currentOffset + ITEMS_PER_PAGE
// get only the items between both cursors and calculate how many pages will there be
setCurrentItems(filteredItems.slice(currentOffset, endOffset))
setPageCount(Math.ceil(bonuses.length / ITEMS_PER_PAGE))
}, [currentOffset, filteredItems])
useEffect(() => {
// Loading items from {currentOffset} to {endOffset}
const endOffset = currentOffset + ITEMS_PER_PAGE
// get only the items between both cursors and calculate how many pages will there be
setCurrentItems(filteredItems.slice(currentOffset, endOffset))
setPageCount(Math.ceil(bonuses.length / ITEMS_PER_PAGE))
}, [currentOffset, filteredItems])
I should have said it before sorry, that's why I am asking if I should make a copy and how I must manage that filteredItems is a copy of bonuses
SS3BAS5/26/2022
I have to go, hope someone else can help you from here
UUUnknown User5/27/2022
Message Not Public
Sign In & Join Server To View

Looking for more? Join the community!

R
Reactiflux

⛄ Snowberb ⛄ – 12-56 May 26

Join Server