Reputation: 71
I'm building a small clothing store app in React, just to learn things. I implemented a filter by price section but I would want to be able to write a condition for the case in which there's no item in the selected price range, instead of the page being blank.
render() {
const filteredOpt2 = this.state.items.filter(item => item.price <= 60);
const filteredOpt3 = this.state.items.filter(item => item.price >= 60 && item.price <= 100);
return (
<div>
{
this.state.selectedOption === "option1"
? <ProductList products={this.state.items} style={{marginLeft: 0}}/>
: this.state.selectedOption === "option2"
? <ProductList products={filteredOpt2} style={{marginLeft: 0}}/>
: this.state.selectedOption === "option3"
? <ProductList products={filteredOpt3} style={{marginLeft: 0}}/>
: null
}
</div>
)
}
I know the code is very repetitive and really not ideal, but I couldn't come up with a better approach for now.
So what I wish to do, is, let's say the filteredOpt2 results in an empty array, how and where could I implement a condition that says if this happens, display a p tag showing a text?
Upvotes: 0
Views: 4501
Reputation: 16309
You can do the filtering in advance, e.g. in a function and then render the list accordingly:
const filterItems = (items, filter) => {
if (filter === "option1") return items;
if (filter === "option2") return items.filter(item => item.price <= 60);
if (filter === "option3") return items.filter(item => item.price >= 60 && item.price <= 100);
};
render() {
const filtered = filterItems(this.state.items, this.state.selectedOption);
return (
<div>
{filtered.length === 0 ? (
<p>No products</p>
) : (
<ProductList products={filtered} style={{marginLeft: 0}}/>
)}
</div>
);
}
or even better let the ProductList
component handle that:
render() {
return (
<div>
<ProductList
products={filterItems(this.state.items, this.state.selectedOption)}
style={{marginLeft: 0}}
/>
</div>
);
}
const ProductList = ({products}) => {
if (products.length === 0) return <p>No products</p>;
return ...
};
Upvotes: 2
Reputation: 26
You are sending the product list down to ProductList
component via props. In that component, where you use your props.products
, you can add something like this:
{!props.products.length
? <p>No product matched the criteria</p>
: props.products.map(product => {... whatever your code is })
}
To elaborate, if the products.length
is zero, you show your 'no product' text, otherwise, show the products.
Upvotes: 1
Reputation: 2866
If not diving deep in the idea of component split you can just add condition in the template like this
const filteredOpt2 = this.state.items.filter((item) => item.price <= 60);
const filteredOpt3 = this.state.items.filter(
(item) => item.price >= 60 && item.price <= 100
);
return (
<div>
{this.state.selectedOption === "option1" ? (
<ProductList products={this.state.items} style={{ marginLeft: 0 }} />
) : this.state.selectedOption === "option2" ? (
<>
{filteredOpt2.length > 0 ? (
<ProductList products={filteredOpt2} style={{ marginLeft: 0 }} />
) : (
<p>No items lower than 60</p>
)}
</>
) : this.state.selectedOption === "option3" ? (
<>
{filteredOpt3.length > 0 ? (
<ProductList products={filteredOpt3} style={{ marginLeft: 0 }} />
) : (
<p>No items between 60 and 100</p>
)}
</>
) : null}
</div>
Upvotes: 2