nomad
nomad

Reputation: 41

How to fix ReactJS filtered search that isn't working properly

I am working on some reactjs project that will show data based on user query. User can type and filtered data by checkbox. It working properly actually, user type something in search bar and record are fetching data correctly. The problem is when user use check box to filter some data, the exact data show up but when they remove/uncheck the checkbox, the filtered data is not show up, instead it show the whole data. I want that, when user remove/uncheck the checkbox from that data they type, it show back the original data that user type. I am sorry if my language is a little bit difficult to understand. I will provide my code please have a look and help me to figure out if I made some mistake, also please tell me what is the best practice to fix this problem. I am beginner to React and does not have much knowledge to fix this problem . Thanks

import React from 'react';
  import logo from './logo.svg';
  import { Dropdown } from 'semantic-ui-react'
  import './App.css'
  import DropdownCheckbox from './components/dropdownCheckbox/dropdownCheckbox';

  class App extends React.Component {
    constructor(props) {
      super(props)

      this.state = {
        furnitureStyles: [],
        products: [],
        checkedFS: [],
        checkedDT: [],
        searchFilt: "",
        filteredProduct: []
      };
    };

    async onDropdownChange(val){
      await this.setState({
        checkedFS: val
      })
      await this.filteredFurnitureStyle()
    }

    fetchData(){
      fetch('http://www.mocky.io/v2/5c9105cb330000112b649af8')
      .then( response => {
        if(response.status === 200){
          return response.json()
        }
      })
      .then(responseJson => {
        this.setState({
          furnitureStyles: responseJson.furniture_styles,
          products: responseJson.products,
          filteredProduct: responseJson.products
        })
      })
    }

    componentDidMount(){
      this.fetchData()
    }

    loadingPage(){
      return(
        <div>
          Please Wait ...
        </div>
      )
    }

    regexDesc(value){
      return value.replace(/(?<=^.{115}).*/, " ...")
    }

    async filteringFunc(e){

      const { checkedDT, checkedFS, searchFilt, products, filteredProduct } = this.state
      if(e.target.value !== "") {
          let search = products.filter(product => product.name.toLowerCase().indexOf(e.target.value.toLowerCase()) !== -1)
          this.setState({
            filteredProduct : search
          }) 
        } else if(e.target.value === ""){
          this.setState({
            filteredProduct: products 
          })
        }
    }

    async onDropdownChange(val){
      await this.setState({
        checkedFS: val
      })
      await this.filteredFurnitureStyle()
    }

    filteredFurnitureStyle = () => {
      const { filteredProduct, checkedFS, products } = this.state
      if(checkedFS.length > 0) {
        let search = filteredProduct.filter(product => (
          checkedFS.findIndex(element => product.furniture_style.indexOf(element) !== -1) !== -1
        ))
        this.setState({
          filteredProduct: search
        })
      } else {
        this.setState({
          filteredProduct: products
        })
      }
    }



    render(){
      const { furnitureStyles, products, checkedDT, checkedFS, filteredProduct } = this.state
        return (
          <div className="App">
            <header>
              <div className="search-section">
                <input type="search"
                  placeholder="Search Furniture ..."
                  className="search-input"
                  onChange={(e)=>this.filteringFunc(e)}
                />
              </div>
              <div className="dropdown-section"
              >
                {furnitureStyles.length > 0 ? (
                  <React.Fragment>
                    <DropdownCheckbox
                      style={{margin:"0 24px"}}
                      defaultSelected="Furniture Style"
                      options={furnitureStyles}
                      onChange={(val)=>this.onDropdownChange(val)}
                    />
                    <DropdownCheckbox
                      style={{margin:"0 24px"}}
                      defaultSelected="Delivery Time"
                      options={["1 week","2 weeks", "1 Month", "more..."]}
                      onChange={val=>this.setState({
                        checkedDT: val
                      })}
                    /> 
                  </React.Fragment>) : "Loading"
                }
              </div>  
            </header>
            <div id="section2">
              <div className="card-section">
                {products.length > 0 && 
                  filteredProduct.map(product => {
                    return (
                      <div className="ui cards flexing">
                        <div className="ui fluid card content">
                          <div className="card-header">
                            <h4>
                              {product.name}
                            </h4>
                            <span>
                              IDR {product.price}
                            </span>
                          </div>
                          <div>
                            <span>
                              {this.regexDesc(product.description)}
                            </span>
                            <div>
                              <ul className="furniture-styles">
                                {product.furniture_style.map(style => {
                                  return (
                                    <li>{style}</li>
                                  )
                                })}
                              </ul>
                            </div>
                          </div>
                          <div>
                            <span>{product.delivery_time} {product.delivery_time > 1 ? "days" : "day"}</span>
                          </div>
                        </div>
                      </div>
                    )
                  }) 
                }
              </div>
            </div>
          </div>
        );
    }
  }

  export default App;

Upvotes: 0

Views: 64

Answers (1)

Clarity
Clarity

Reputation: 10873

await this.setState isn't gonna work. If you need to call a function after updating a state, use setState's callback function:

onDropdownChange = (val) => {
  this.setState({
    checkedFS: val
  }, this.filteredFurnitureStyle) // Use callback
}

Upvotes: 2

Related Questions