0

i have the the following array of object which indicated all the possible combination of a product

[{id:25,attributes:[{id: 0, name: "Weight", option: "250gr"},{id: 0, name: "Roast", option: "Medium"},{id: 0, name: "Packaging", option: "Card"}
{id:26,attributes:[{id: 0, name: "Weight", option: "500gr"},{id: 0, name: "Roast", option: "Medium"},{id: 0, name: "Packaging", option: "Card"}
{id:27,attributes:[{id: 0, name: "Weight", option: "250gr"},{id: 0, name: "Roast", option: "Light"},{id: 0, name: "Packaging", option: "Card"}
{id:28,attributes:[{id: 0, name: "Weight", option: "250gr"},{id: 0, name: "Roast", option: "Light"},{id: 0, name: "Packaging", option: "Tin"}
]

On the webpage, options are set via select; the select also set a state component as follow:

{Weight:"",Roast:"",Pakaging:""}

with the values from the selected option, for example (assuming only weight and roast are selected):

{Weight:"250gr",Roast:"Light",Packaging:""}

everytime a option is selected i want to narrow down the combination of product (based on the selection) until i finally got only one option available (also the combination are used for dinamically repopulate select, adding or removing available options based on previous selections)

until now i was using something like (inside the function called by onChange on a select):

const result = variations.filter((p) =>
  p.attributes.some((c) => c.option === event.target.value)
);

but this way it reduces based on the latest selection, so if i start selecting 250gr it gives me a set of 3 (25,27,28) then if i select Medium, it give me a set of 2 (25 and 26) filtering only on medium and ignoring Weight

i'm looking to convert my filter, instead that on event.target.value, on the object but i cant find the right method, anyone can help?

2
  • Can you post the complete code s owe get a better picture of what your doing? Commented Dec 9, 2020 at 20:37
  • @MosheSommers Here is my code codesandbox.io/s/elegant-tereshkova-7uovc?file=/src/App.js Commented Dec 10, 2020 at 10:00

1 Answer 1

1

You need to persist the selected filters like this:

const [filters, setFitlers] = React.useState({});
const onFilterChange = (e) => {
        setFitlers(prevFilters => ({...prevFilters, [e.target.name]: e.target.name})
   }

Now you can filter like this:

const result = variations.filter((p) =>
  Object.entries(filters).every(([key, value]) => p.attributes[key] === value)
);

Obejct.entries will give you the key and value pairs of the filter object. And with every, you check if all the filters match.

Now you only have to give the input a name to fit your name:

<input name="weight" onChange={onFilterChange} .../>

To remove filters, maybe filter the filter object as well to remove empty strings:

Object.entries(filters).filter(([key,value) => value).every.... 
Sign up to request clarification or add additional context in comments.

5 Comments

i tried the state approach, saved the full object in a filtered one and everytime i change a select (there is an arbitarary number of select on the page) i filter and set the state again with filtered one; it worked on filtering down (i can arrive to one result setting all the select) but it does not unfilter and im unable to keep track of what are the available options it looks like a more complex problem of what i was talking
Here is my code codesandbox.io/s/elegant-tereshkova-7uovc?file=/src/App.js its not worrking as expected at all, i made a lot of confusion on it :( for example if i select 250gr in the first field it set the second and third in the correct way, but once in the secondi select something it reset back to non filtered ones
Ok you have a quite nested data structure. Check this out: codesandbox.io/s/interesting-ives-jldhz?file=/src/App.js. You need to listen to the changes outside of the onChange to get all needed information, since setting state is async.
Thank you! this solve part of my problem, it doesnt filter out the main atributes from unavailable options (so it wont lead to empty variations array), also i have to consider that if the selected option is the first or only, this shouldn't be filtered out
That looks like you just needs some adjustments. Glad to have helped. If that answered your question, could you mark it as selected?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.