0

I am retrieving a list of data and search for a title name from a list of todos, then i have built with Switch Material UI a component to toggle the todos that are completed and not.

You can see the full demo here => https://codesandbox.io/s/so-68247206-forked-sx9kv?file=/src/App.js

Now i want to search the todos title in the list of the todos/tasks that are completed or not completed, depending on where you switch, at the moment the search goes through in all the todos.

To reproduce the case

  • Launch the app in codesandbox
  • Switch the toggle
  • Search for elements (It search in all the todos list and not through the completed or not completed result list )

The relevant code is the following

The search method

  const handleSearch = (event) => {
    let value = event.target.value.toLowerCase();
    let result = [];
    result = tasks.filter((data) => {
      return data.title.search(value) !== -1;
    });
    setFilteredData(result);
  };

The complete method

  const getCompleted = (e, value) => {
    let result = [];
    let switchValue = e.target.checked;
    result = tasks.filter(({ completed }) => completed === switchValue);
    setFilteredData(result);
    setIsCompleted(!switchValue);
    setText(isCompleted ? "Yes" : "No");
  };

How can i change my search method to look through the todos completed and not completed?

Anish Antony
  • 1,379
  • 8
  • 13
Koala7
  • 1,340
  • 7
  • 41
  • 83

3 Answers3

1

There's a slight modification to your handleSearch method. When you're filtering your tasks, you can check if you have toggled on the completed switch using the isCompleted state. All you need is an additional condition inside your filter method that takes care of the is completed scenario. The following updated handleSearch method works fine.

  const handleSearch = (event) => {
    let value = event.target.value.toLowerCase();
    let result = [];
    console.log(value);
    let filterCompleted = false;
    if (!isCompleted) filterCompleted = true;
    console.log({ filterCompleted });
    result = tasks.filter((data) => {
      if (filterCompleted)
        return data.completed && data.title.search(value) !== -1;
      else return !data.completed && data.title.search(value) !== -1;
    });
    setFilteredData(result);
  };

I use a local variable inside handleSearch to check if you have toggled on the completed button. If it's toggled on, while filtering I only filter those tasks that have the completed property set to true and vice versa. You can check that this works here https://codesandbox.io/s/so-68247206-forked-4iz7p?file=/src/App.js.

Note: I feel the isCompleted state is working on a reverse logic. When I toggle on the switch, the isCompleted is false but it should be true instead. You can try fixing this or renaming the state (if the reverse logic was intentional and you only messed up with naming the state). Anyhow this doesn't affect the solution but makes it difficult to debug and adds some confusion.

Siddhant Varma
  • 574
  • 5
  • 10
1

Your filter in handleSearch searches from the original tasks array which might not be what you want :

   const handleSearch = (event) => {
    let value = event.target.value.toLowerCase();
    let result = tasks; //Assigning initial value to result
    if(isCompleted){
     result =  result.filter(({ completed }) => completed === isCompleted)
    } //only if isCompleted is true, filter the array first
    result = result.filter((data) => {
      return data.title.search(value) !== -1;
    }); //Filter the array based on search term
    setFilteredData(result);
  };

Also, your getCompleted is setting the inverse value of the checkbox with (!switchValue). You can change that along with the extra param value which is not accounted for in your onChange call.

 const getCompleted = (e) => {
    
    let switchValue = e.target.checked;
    let result = tasks.filter(({ completed }) => completed === switchValue);
    setFilteredData(result);
    setIsCompleted(switchValue);
    setText(switchValue ? "Yes" : "No"); //Is text state variable really required?
  };

Here I have tried to fix it : CodeSandbox

That being said, I would recommend not having multiple state variables which can be derived from each other. Your text state variable is only used for view purposes and its value completely relies on isCompleted. You could have used a conditional operator in your return function to show "Yes/No" instead of a new state variable.

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39
0

You have to save both the search value and switch value in state and use a useEffect to filter the values. Check the below fork of your code

https://codesandbox.io/s/so-68247206-forked-nkuf3?file=/src/App.js

Anish Antony
  • 1,379
  • 8
  • 13
  • This is the best solution, although the initial list is filtering already the not completed, haw can i solve that? – Koala7 Jul 06 '21 at 10:52
  • 1
    It's because we were setting the isCompleted default in useState. Also modified the filtering to check for boolean value in isCompleted , check here https://codesandbox.io/s/so-68247206-forked-xn3nn?file=/src/App.js – Anish Antony Jul 06 '21 at 11:05
  • 1
    thanks, i have learnt a lot with your answer – Koala7 Jul 06 '21 at 11:11