0

I Have this array I wants to filter based on checkbox checked values Using React.

const invoice = [
  {
    id: "RT3080",
    createdAt: "2021-08-18",
    paymentDue: "2021-08-19",
    description: "Re-branding",
    paymentTerms: 1,
    clientName: "Jensen Huang",
    clientEmail: "[email protected]",
    status: "paid",
  },
  {
    id: "XM9141",
    createdAt: "2021-08-21",
    paymentDue: "2021-09-20",
    description: "Graphic Design",
    paymentTerms: 30,
    clientName: "Alex Grim",
    clientEmail: "[email protected]",
    status: "pending",
  },
  {
    id: "RG0314",
    createdAt: "2021-09-24",
    paymentDue: "2021-10-01",
    description: "Website Redesign",
    paymentTerms: 7,
    clientName: "John Morrison",
    clientEmail: "[email protected]",
    status: "paid",
  },
  {
    id: "TY9141",
    createdAt: "2021-10-01",
    paymentDue: "2021-10-31",
    description: "Landing Page Design",
    paymentTerms: 30,
    clientName: "Thomas Wayne",
    clientEmail: "[email protected]",
    status: "pending",
  },
  {
    id: "FV2353",
    createdAt: "2021-11-05",
    paymentDue: "2021-11-12",
    description: "Logo Re-design",
    paymentTerms: 7,
    clientName: "Anita Wainwright",
    clientEmail: "",
    status: "draft",
  },
];

I set up a useState as an object to store the objects i want to filter with which is this

 const [check, setcheck] = useState({
    paid: false,
    pend: false,
    draft: false,
  });

Then I added an onchange event handler to each checkbox that I created

<input
  checked={check.pend}
  onChange={(e) => onChange(e)}
  type="checkbox"
  name="pend"
  value="pending"
/>;

<input
  checked={check.draft}
  onChange={(e) => onChange(e)}
  type="checkbox"
  name="draft"
  value="draft"
/>;

<input
  checked={check.paid}
  onChange={(e) => onChange(e)}
  type="checkbox"
  name="paid"
  value="paid"
/>;

The onChange event handler below

 const onChange = (e) => {
    setcheck({ ...check, [e.target.name]: e.target.checked });
  };

so the problem is this, I wanna filter the array of objects using the checkbox checked values i.e if the onChange is triggered i wanna run a function that will filter the array and return only where the status === checked checkbox value.

so i created an handleChange function which i later added to onchange function. so the function now looks like this

const onChange = (e) => {
    setcheck({ ...check, [e.target.name]: e.target.checked });
    handleChange(e);
  };

and the handleChange function it self

  const handleChange = (e) => {
    let tempInvoice = [...invoice];

    if (e.target.name === "pend" && e.target.checked === true) {
      tempInvoice = tempInvoice.filter((inv) => {
        return inv.status === e.target.value;
      });
    }
    if (e.target.name === "paid" && e.target.checked === true) {
      tempInvoice = tempInvoice.filter((inv) => inv.status === e.target.value);
    }
    if (e.target.name === "draft" && e.target.checked === true) {
      tempInvoice = tempInvoice.filter((inv) => inv.status === e.target.value);
    }
console.log(tempInvoice);
  };

With the Above information provided, my tempInvoice only logs out newly curent checked items. i.e if I checked the draft checkbox, it would only return array that has the status.draft . if I checked both draft and paid, It would only return the Array that has Paid in it and not both. and I want this functionalities to work in a way that if I check both draft and paid. It should only return Array that the status of paid and draft.

3
  • How do I ask a good question?: "Write a title that summarizes the specific problem" - An unspecific question is not a specific problem. Commented Sep 3, 2021 at 16:02
  • Why do you have three separate ifs that all do the same? if(["pend", "paid", "draft"].includes(e.target.name) && e.target.checked) { ... } Commented Sep 3, 2021 at 16:04
  • Am Literally new to Javscript and i couldnt think of that You can help me refactor the handleChange function.. Commented Sep 3, 2021 at 16:08

2 Answers 2

0

I would suggest you use setCheck instead of setcheck.

const[check, setCheck] = useStage({});

const onChange = (e) => {
    const newCheck = { ...check, [e.target.name]: e.target.checked };
    setCheck(newCheck);
    handleChange(newCheck);
  };

 const handleChange = (check) => {
    let tempInvoice = [...invoice];

    //if none checked
    if(!check.pend && !check.paid && !check.draft) {
       console.log(tempInvoice);
       return;
    }

    //if all checked
    if(check.pend && check.paid && check.draft) {
       console.log(tempInvoice);
       return;
    }
   tempInvoice = invoice.filter((inv) => {
        return (inv.status === "pending" && check.pend)
              || (inv.status === "paid" && check.paid)
              || (inv.status === "draft" && check.draft);
      });
console.log(tempInvoice);
  };
Sign up to request clarification or add additional context in comments.

2 Comments

Am Wowed, I tried this and it works But there is a problem, if I check everything and uncheck everything, the tempInvoice returns an empty array
it still didnt work but have marked your solution as the answer and through your own solution i was able to refactor everything and get it working as expected.
0

Everything works as expected on the above code John Posted but if I check the checkboxes and Uncheck them. The filter Item returns an empty array but rather should have returned The Previous Array. So I added a little code to get back previous array.

const[check, setCheck] = useStage({});

const onChange = (e) => {
    const newCheck = { ...check, [e.target.name]: e.target.checked };
    setCheck(newCheck);
    handleChange(newCheck);
  };

 const handleChange = (check) => {
    let tempInvoice = [...invoice];

    
   
   tempInvoice = invoice.filter((inv) => {
        return (inv.status === "pending" && check.pend)
              || (inv.status === "paid" && check.paid)
              || (inv.status === "draft" && check.draft);
      });
 if (
      !check.pend &&
      !check.paid &&
      !check.draft &&
      invoice.length > 0
    ) {
      tempInvoice = [...invoice];
    }

console.log(tempInvoice);
  };

2 Comments

I do not think what you add is necessary, it must something else, I noticed you have this: currentInvoice
@JohnDing it was a mistake and it as been corrected

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.