Rgreaner
Rgreaner

Reputation: 31

Trouble with React/JS filter

I am trying to implement a filter function that is able to search in two separate JSON fields when a user types in a search bar. Searching the whole JSON returns errors and if I repeat this function, the two similar functions cancel each other out.

My current filter function:

let filteredOArt = origArt.filter((origAItem) => {
                return origAItem.authors.toLowerCase().includes(this.state.search.toLowerCase())
            });

I want to be able to have the search look within the "authors" field as well as a "description" field.

Before the React render, I have this function listening to the state:

updateSearch(event) {
    this.setState({ search: event.target.value }) 
}

Then my search function is in an input field in the React return:

<h6>Search by author name: <input type="text" value={this.state.search} onChange={this.updateSearch.bind(this)} /></h6>

Upvotes: 1

Views: 87

Answers (3)

Treycos
Treycos

Reputation: 7492

You could use some to check if the filter is positive for at least one field :

let filteredOArt = origArt.filter(origAItem => ['authors', 'description'].some(field => origAItem.[field].toLowerCase().includes(this.state.search.toLowerCase())))

Just iterate over the different field names you want to use.

Some will return true if any of the fields mentioned contains your string and avoid repetitions in your code.

Long syntax :

origArt.filter(origAItem => {
    return ['authors', 'description'].some(field => origAItem.[field].toLowerCase().includes(this.state.search.toLowerCase()))
})

Upvotes: 1

grenzbotin
grenzbotin

Reputation: 2565

You actually can do a filter for both fields.

Given you have your searchValue and your array with the objects you could filter this way:

const filterByAuthorOrDescription = (searchValue, array) =>
  array.filter(
    item =>
      item.authors.toLowerCase().includes(searchValue.toLowerCase()) ||
      item.description.toLowerCase().includes(searchValue.toLowerCase())
  );
const filtered = filterByAuthorOrDescription(this.state.search, articles);

filtered will now contain an array of objects that contain your searchValue in either description or authors that you can map through.

Upvotes: 1

You can tweak the function a bit like this

let filteredOArt = origArt.filter((origAItem) => {
       return (
(origAItem.authors.toLowerCase().includes(this.state.search.toLowerCase())||

(origAItem.description.toLowerCase().includes(this.state.search.toLowerCase())
       )
)
        });

Upvotes: 1

Related Questions