2

I made a todo app and I wanted to improvise it by showing all completed task

enter image description here

Checking "Show completed task" works fine and shows me all completed task using the code below

// App.js
filterCompleted = () => {
  this.setState({todos: [...this.state.todos.filter(todo => {return todo.completed === true})]})
}

// NavBar.js
<input type="checkbox" onChange={ () => this.props.filterCompleted()}></input> <span> Show completed 
task</span>

Un-checking the "Show completed task" should bring me back the original state
I tried checking if the checkbox is checked or not but the code below doesn't seems to work.
// App.js
filterCompleted = (filter) => {
if(filter.checked){
  alert('checked')
  //this.setState({todos: [...this.state.todos.filter(todo => {return todo.completed === true})]})
}
else{
  alert('unchecked  ')
    }
}

//NavBar.js
input type="checkbox" onChange={() => this.props.filterCompleted(this)}></input> <span> Show completed task</span>

2 Answers 2

1

Try to send event inside input:

<input type="checkbox" onChange={event => this.props.filterCompleted(event)}></input> 
<span> Show completed task</span>

Or just:

<input type="checkbox" onChange={this.props.filterCompleted}></input> 
<span> Show completed task</span>

And in App.js:

filterCompleted = event => {
   if(event.target.checked){
      alert('checked')
   } else {
     alert('unchecked  ')
   }
}
Sign up to request clarification or add additional context in comments.

1 Comment

both works, i have a lil problem on the else/uncheck statement, it does not give me my original state...
0

You need to send the state of the checkbox to decide whether to filter or not:

// App.js
filterCompleted = (filter) => {
  this.setState({filteredTodos: [...this.state.todos.filter(todo => filter ? todo.completed : true)]})
}

// NavBar.js
<input type="checkbox" onChange={ e => this.props.filterCompleted(e.target.checked)}></input> <span> Show completed 
task</span>

Make sure to iterate over state.filteredTodos in the view, not state.todos, and make sure to run this.filterCompleted(false) at the start so filteredTodos is set to the full array.

Note there is a better way to do this, which is to filter the todos in the render function. Something like:

render() {
    const filtered = this.state.todos.filter(t => this.state.filterCompleted ? t.completed : true);
    return (
        this.filtered.map(...); // render component here
    )
}

In that case you would simply toggle state.filterCompleted when the user toggles the checkbox.

(Note the slight simplification of the arrow function. If your arrow function begins with return, then get rid of the braces and the return. An arrow function without braces has an implicit return. Makes it simpler and easier to read.)

4 Comments

works, i'm having trouble upon unchecking the checkbox, it should give me all the state whether completed or not.
The code above should do that. What are you seeing?
after checking "Show completed task" it shows the completed task, after unchecking, the completed task remains as if nothing happens.
Ah OK I get it. We need to keep track of the unfiltered list. My mistake. Code edited.

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.