john
john

Reputation: 39

React filter function

I am new and studying React. I am trying to make a search filter, I followed the youtube and made a function. But it did not work with the error "Array.prototype.filter() expects a value to be returned at the end of arrow function array-callback-return". I have done everything. It still did not work. Anyone help please.

          const boards = this.state.boards.filter((board)=>{
                if(this.state.search == null)
                    return board
                else if(board.title.toLowerCase().includes(this.state.search.toLowerCase()) || board.content.toLowerCase().includes(this.state.search.toLowerCase())){
                    return board
                }
              }).map(board=>{
                return(
                    <tr key = {board.idx}>
                    <td> {board.idx} </td>
                    <td><button  className="btn btn-link" onClick = {() => this.BoardDetail(board.idx)}> {board.title}</button></td>
                    <td> {board.insertTime} </td>
                    <td> {board.updateTime} </td>
                    <td> {board.viewCnt} </td>
                </tr>
                )
                })

Upvotes: 0

Views: 801

Answers (3)

Pranay Binju
Pranay Binju

Reputation: 621

Instead of filter, you can try using reduce that will be bit easy like following:

const boards = this.state.boards.reduce((acc,board) => {
      if(this.state.search == null)
                    return acc.concat(board);
      else if(board.title.toLowerCase().includes(this.state.search.toLowerCase()) || board.content.toLowerCase().includes(this.state.search.toLowerCase())){
                    return acc.concat(board);
           }
           //else return acc
           return acc;
    },[])
    .map(/* ...the rest of your map function */)

Upvotes: 0

Giovanni Esposito
Giovanni Esposito

Reputation: 11166

Your problem is on filter function: not all the paths return something (I mean, on internal if you forgot to add final else case).

But you could make things more easy. Infact, considering that filter function wants a boolean condition (to filter this.state.boards elements) you could write something like:

const boards = this.state.boards.filter((board)=>{
                return this.state.search === null || (board.title.toLowerCase().includes(this.state.search.toLowerCase()) || board.content.toLowerCase().includes(this.state.search.toLowerCase()))
              }).map(board=>{
                return(
                    <tr key = {board.idx}>
                    <td> {board.idx} </td>
                    <td><button  className="btn btn-link" onClick = {() => this.BoardDetail(board.idx)}> {board.title}</button></td>
                    <td> {board.insertTime} </td>
                    <td> {board.updateTime} </td>
                    <td> {board.viewCnt} </td>
                </tr>
                )
                })

Just put your conditions in or and error disappears.

Upvotes: 0

Chan Youn
Chan Youn

Reputation: 892

Making assumptions here, since as user Mohit Kushwaha stated, the initial state is necessary to debug properly.

Your filter functions are returning the wrong "type" of value. if you look at Array.prototype.filter, you'll notice that the callback asks for a function that will return a true or false value.

callbackFn

Function is a predicate, to test each element of the array. Return a value that coerces to true to keep the element, or to false otherwise.

What this means is that instead of returning board in your filter function, you should return true/false. In the example below I'm returning true when I think you are trying to keep something in the array - for example when the this.state.search matches your board's title or content, and false when you want to remove it, for example if there is no match (again making assumptions - you should really try to formulate your question with as much relevant detail):

const boards = this.state.boards.filter((board) => {
  if(this.state.search == null) {
    // If there is no search value, don't filter anything
    return true 
  } else if (
    board.title.toLowerCase()
      .includes(this.state.search.toLowerCase()) || 
    board.content.toLowerCase()
      .includes(this.state.search.toLowerCase())
  ) {
    // If the search string matches, keep the `board` 
    return true 
  } else {
    // If there is a search string and it does not match, filter out the `board` 
    return false 
  }
})
.map(/* ...the rest of your map function */)

Upvotes: 1

Related Questions