0

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>
                )
                })
2
  • please add the initial state also to question Commented Aug 11, 2021 at 5:10
  • If both the conditions inside the callback failed, then it will return undefined, which can cause error. Commented Aug 11, 2021 at 8:25

3 Answers 3

1

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 */)
Sign up to request clarification or add additional context in comments.

Comments

0

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.

1 Comment

@john no problem. Happy coding =)
0

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 */)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.