Eva Lilith
Eva Lilith

Reputation: 21

Filter search with ReactJs and mobx

I'm trying to do a filter search input for an imported list of items (title and description) using mobx-react instead of state. But when I type in the input, in the console I'm getting [object object], and of course is not filtering nothing. Here is my code, I'm new with mobx. Can anyone help me? Thanks in advance!!!

import React from "react";
import items from "../pages/items";
import {observable, action, computed, decorate} from 'mobx';
import {observer} from 'mobx-react';


class Searchbar extends React.Component {
  filterTermValue = [];
  itemsList = items

  get filtered() {
    let filteredList = this.itemsList.filter(
    t=>(t.title && t.description).indexOf(this.filterTermValue)>-1 
    );

    if (filteredList.length)
      return filteredList;
      return this.itemsList;

    }

  render() {
    return (
      <div>
          Term: <input placeholder="Search"
                  onKeyUp={this.onChangeFilterTerm} />

          {this.filtered.map(item =>
              <div key={item.index}>
                <h5>{item.title}</h5>
                <p>{item.description}</p>
              </div>
            )}
      </div>
    )
  }

   onChangeFilterTerm = value => {
    this.filterTermValue = value.toString().toLowerCase();
    console.log(this.filterTermValue)
  }
}
decorate(Searchbar, {
  filterTermValue: observable,
  itemsList: observable,
  filtered: computed,
  onChangeFilterTerm: action
});


export default Searchbar

Upvotes: 2

Views: 1998

Answers (1)

Radovan Šurl&#225;k
Radovan Šurl&#225;k

Reputation: 91

hope it's not too late.

Seems like you weren't retrieving the event.target.value in your onChangeFilterTerm method.

I've created a working version for you here:

class Searchbar extends React.Component {
  constructor() {
    super();
    this.state = {
      filterTermValue: "",
      itemsList: [{
          title: "Think and Grow Rich",
          description: "a book"
        },
        {
          title: "bbb",
          description: "ccc"
        }
      ]
    };
  }

  get filtered() {
    let filteredList = this.state.itemsList.filter(item =>
      item.title.toLowerCase().includes(this.state.filterTermValue) || item.description.toLowerCase().includes(this.state.filterTermValue)
    );

    if (filteredList.length) return filteredList;
    return this.state.itemsList;
  }

  render() {
    return ( <
      div >
      Term: < input placeholder = "Search"
      onKeyUp = {
        this.onChangeFilterTerm
      }
      /> {
        this.filtered.map(item => ( <
          div key = {
            item.index
          } >
          <
          h5 > {
            item.title
          } < /h5> <
          p > {
            item.description
          } < /p> <
          /div>
        ))
      } <
      /div>
    );
  }

  onChangeFilterTerm = event => {
    this.setState({
      filterTermValue: event.target.value.toString().toLowerCase()
    });
  };
}

ReactDOM.render( < Searchbar / > , document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

I've used the traditional state approach to get this working fast, since I am not too used to using class properties.

Hope it can help, if not, I will be glad to help out.

Upvotes: 1

Related Questions