Reputation: 25
I have to filter this array on 2 ways, one is while the user types and the other is when he clicks on some category, and my code is like this:
https://gist.github.com/pedroapfilho/dbd48b1bf10c4ff625929cb2f67c6b41
import React, { Component } from "react";
import "./App.css";
import appslist from "../apps.json";
import Sidebar from "../components/Sidebar/Sidebar";
import HeaderSearch from "../components/HeaderSearch/HeaderSearch";
import ListContainer from "../components/ListContainer/ListContainer";
import Pagination from "../components/Pagination/Pagination";
class App extends Component {
state = {
list: appslist,
searchfield: "",
selectedcategory: "",
currentpage: 1,
itensperpage: 3
};
onSearchChange = event => {
this.setState({ searchfield: event.target.value });
};
onClickCategory = event => {
this.setState({ selectedcategory: event.target.id });
};
render() {
const {
list,
searchfield,
currentpage,
itensperpage,
selectedcategory
} = this.state;
let filteredList;
filteredList = list.filter(list => {
return list.name.toLowerCase().includes(searchfield.toLowerCase());
});
filteredList = list.filter(list => {
return list.categories[0].toLowerCase().includes(selectedcategory.toLowerCase());
});
return (
<div className="flex-container">
<Sidebar categorylist={list} selectedCategory={this.onClickCategory} />
<section className="apps-list">
<HeaderSearch searchChange={this.onSearchChange} />
<ListContainer list={filteredList} />
<Pagination currentPage={currentpage} itensperpage={itensperpage} />
</section>
</div>
);
}
}
export default App;
I kept both filteredList
there, but only the last one will work
How can I make both works at the same time?
Upvotes: 0
Views: 3902
Reputation: 2237
You can chain the filters:
filteredList = list
.filter(list => list.name.toLowerCase().includes(searchfield.toLowerCase()))
.filter(list => list.categories[0].toLowerCase().includes(selectedcategory.toLowerCase()));
Or even write it as a single filter:
filteredList = list.filter(
list => list.name.toLowerCase().includes(searchfield.toLowerCase()) &&
list.categories[0].toLowerCase().includes(selectedcategory.toLowerCase())
);
If you need the OR behavior instead of AND, then use the single filter approach and replace &&
with ||
, obviously.
Regarding question from comment:
To use all categories in your filter you may use some
or every
(depending on desired logic):
filteredList = list.filter(
list => list.name.toLowerCase().includes(searchfield.toLowerCase()) &&
list.categories.some(
cat => cat.toLowerCase() === selectedcategory.toLowerCase()
)
);
Upvotes: 1