0

I tried to implement search/filter function on reactjs app. User can search anything and object should return based on search value. Search logic implemented in handleChange. Can anyone let me know where I made mistake?

It's doesn't return any errors. Just screen gone blank

Shipment.tsx

export class Shipment extends Component<object, ListInterface> {
  constructor(props: any) {
    super(props);
    this.state = {
      list: [] as any[],
      value: ''
    };
    this.handleChange = this.handleChange.bind(this);
  }

  componentDidMount() {
    this.getShipmentList();
  }

  componentWillReceiveProps(nextProps: any) {
    this.setState({
      list: nextProps.list
    });
  }

  getShipmentList() {
    axios.get('http://localhost:3001/shipments').then((res: any) => {
      this.setState({ list: res.data });
    });
  }

  handleChange(e: any) {
    let currentList = [];
    let newList = [];

    if (e.target.value !== '') {
      currentList = this.state.list;

      newList = currentList.filter((item: any) => {
        const lc = item.toString().toLowerCase();
        const filter = e.target.value.toString().toLowerCase();

        return lc.includes(filter);
      });
    } else {
      newList = this.state.list;
    }
    this.setState({
      list: newList
    });
  }

  render() {
    return (
      <div>
        <Card className="Card">
          <CardContent className="Card-Content">
            <Grid container spacing={3}>
              <Grid item xs={12}>
                <div className={`Card-Content__SearchBar`}>{statusList}</div>
                <div className="Card-Content__Location">
                  <TextField
                    id="outlined-name"
                    label="Search"
                    margin="normal"
                    variant="outlined"
                    fullWidth={true}
                    onChange={this.handleChange}
                  />
                </div>
              </Grid>
            </Grid>
          </CardContent>
        </Card>
        {this.state.list.map((item: any, index: number) => (
          <ShipmentList key={index} value={item} />
        ))}
      </div>
    );
  }
}

export default Shipment;

db.json

{
    "id": "S1002",
    "name": "PO89634, PO27X",
    "cargo": [
      {
        "type": "Bikes model 27X",
        "description": "100 Bikes model 27X",
        "volume": "100"
      }
    ],
    "mode": "air",
    "type": "LCL",
    "destination": "Saarbrücker Str. 38, 10405 Berlin",
    "origin": "Shanghai Port",
    "services": [
      {
        "type": "customs"
      }
    ],
    "total": "10000",
    "status": "COMPLETED",
    "userId": "U1001"
  },
SKL
  • 1,243
  • 4
  • 32
  • 53

2 Answers2

4

Your list has a name prop, so you probably want to filter based on that

handleChange(e: any) {
  let list = this.state.list.concat();
  const {value} = e.target; 

  if (value) {
    list = list.filter((item: any) => {
      const name = item.name.toLowerCase();
      const id = item.id.toLowerCase();
      const filter = value.toLowerCase();

      return name.includes(filter) || id.includes(filter);
    });
  } 
  this.setState({
    list
  });
}
Clarity
  • 10,730
  • 2
  • 25
  • 35
1

first you are using componentDidMount(), you have to use componentWillMount() function to load server data into list state then create another filtered list state which will show you filtered data when you type in the input field. Don't overwrite your list data else you again have to fetch data from server. Use filteredlist for search. componentDidMount() runs after the render() function and your state won't be initialize to be used in render()


state =  {
list: [],
filteredlist: [],
values: ''
}

componentWillMount() {
    this.getShipmentList();
}

handleChange(){as above}

Pawan Sah
  • 21
  • 4