0

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?

3 Answers 3

2

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>
Sign up to request clarification or add additional context in comments.

Comments

2

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 ...
};

Comments

1

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.

Comments

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.