I am building a project that displays some data from api and now I need to filter it.
I've done the category filter and now I have to do a price range filter so both these filters could work together, but I'm struggling how to do this right. For price range filter I use 2 inputs and a submit button.
I got an array of objects, looks like this;
filterData = [
{ name: 'Aang', bender: 'yes', nation: 'Air', person: 'yes', show: 'ATLA', price: 132342 },
{ name: 'Appa', bender: 'yes', nation: 'Air', person: 'no', show: 'ATLA', price: 1322 },
{ name: 'Asami', bender: 'no', nation: 'Republic City', person: 'yes', show: 'LOK', price: 132342 },
{ name: 'Azula', bender: 'yes', nation: 'Fire', person: 'yes', show: 'ATLA', price: 12342 }, etc]
I have the state:
state = {
data: [],
nation: '',
priceStart: '',
priceEnd: ''
}
A function that sets state if my bender state has changed Also there are similar functions for start and end states When I set state for prices I parseInt it, so I have a number in state, btw I get a warning every time I enter some digit and then delete it, it says Received a NaN for the 'value' attribute
chFilter = (type, val) => {
switch(type) {
case 'nation':
this.setState({ nation: val });
break;
case 'priceStart':
this.setState({ priceStart: val });
break;
case 'priceEnd':
this.setState({ priceEnd: val });
break;
default:
break;
}
}
getBenders = () => {
const { data, category, priceStart, priceEnd } = this.state;
if( nation || priceStart || priceEnd ){
return data.filter(this.filterBender);
} else {
return data;
}
}
filterBender = data => {
let { nation, priceStart, priceEnd } = this.state;
if(data.nation !== nation) return false;
if(data.price < priceStart) return false;
return true;
}
As I think I need to do a mon function for all the states so it could watch the changes of state and return filtered data. Help how to do this right
I am building a project that displays some data from api and now I need to filter it.
I've done the category filter and now I have to do a price range filter so both these filters could work together, but I'm struggling how to do this right. For price range filter I use 2 inputs and a submit button.
I got an array of objects, looks like this;
filterData = [
{ name: 'Aang', bender: 'yes', nation: 'Air', person: 'yes', show: 'ATLA', price: 132342 },
{ name: 'Appa', bender: 'yes', nation: 'Air', person: 'no', show: 'ATLA', price: 1322 },
{ name: 'Asami', bender: 'no', nation: 'Republic City', person: 'yes', show: 'LOK', price: 132342 },
{ name: 'Azula', bender: 'yes', nation: 'Fire', person: 'yes', show: 'ATLA', price: 12342 }, etc]
I have the state:
state = {
data: [],
nation: '',
priceStart: '',
priceEnd: ''
}
A function that sets state if my bender state has changed Also there are similar functions for start and end states When I set state for prices I parseInt it, so I have a number in state, btw I get a warning every time I enter some digit and then delete it, it says Received a NaN for the 'value' attribute
chFilter = (type, val) => {
switch(type) {
case 'nation':
this.setState({ nation: val });
break;
case 'priceStart':
this.setState({ priceStart: val });
break;
case 'priceEnd':
this.setState({ priceEnd: val });
break;
default:
break;
}
}
getBenders = () => {
const { data, category, priceStart, priceEnd } = this.state;
if( nation || priceStart || priceEnd ){
return data.filter(this.filterBender);
} else {
return data;
}
}
filterBender = data => {
let { nation, priceStart, priceEnd } = this.state;
if(data.nation !== nation) return false;
if(data.price < priceStart) return false;
return true;
}
As I think I need to do a mon function for all the states so it could watch the changes of state and return filtered data. Help how to do this right
Share edited Aug 6, 2019 at 16:01 Stan asked Aug 5, 2019 at 12:27 StanStan 1301 gold badge2 silver badges9 bronze badges2 Answers
Reset to default 8You should write a new filter function which merges these filters together. And use it like this:
filterBender = data => {
const {bender, person, nation} = this.state;
if(bender && data.bender !== bender) return false;
if(person && data.person !== person) return false;
if(nation && data.nation !== nation) return false;
...
return true;
}
const visibelBenders = filterData.filter(filterBender);
This way, you will only filter your data once and every bender gets evaluated for each constraint once. At the end, only the bender which returns true for all the different ifs will be inserted into the visibelBenders array, which you could render. Additionally, you could wrap this into a memorization function to only execute it, if one of the filters changed.
To display all benders, if no filter is set you could wrap the filter into a new function to check if filtering is enabled.
const getBenders = () => {
const { bender, person, nation} = this.state;
if( person || bender || nation ){
return this.filterData.filter(filterBender);
} else {
return this.filterData;
}
}
const benders = getBenders();
i have same problem with marge filters i have two filters and each one works fine but together not works only first work my code is
const [search, setSearch] = useState('');
const [select, setSelect] = useState('All');
const updateSearch = (e) => {
setSearch(e.target.value);
//console.log(search);
}
const updateSelect = (e) => {
setSelect(e.target.value);
//console.log(select);
}
const searchCountry = zemlje.filter((zemlja) => {
if (zemlja.name.toLowerCase().search(new RegExp(`^${search}`)) === 0) return true;
});
const selectCountry = zemlje.filter((zemlja) => {
if (select ==='All') return true;
if (zemlja.region === select) return true;
});
i want filter this base on search input and select drop menu
<div className="atlas">
{searchCountry.map(zemlja => (
<JednaZemlja
key={zemlja.alpha3Code}
name={zemlja.name}
flag={zemlja.flag}
population={zemlja.population}
region={zemlja.region}
capital={zemlja.capital}
/>
))}