0

I would like to get just the "true" checkboxes, to insert then into a my db.

I have an array of categories:

categories_all: [
{
    cat_key: "catfood"
    at_name: "catfood"
    id: 2
    kindof: "food"
    label: "Cat Food"
},

ect... ]

I map them in checkboxes:

  const [checkedItems, setCheckedItems] = useState({})


  const handleCheckChange = event => {

    setCheckedItems({
      ...checkedItems,
      [event.target.name]: event.target.checked,
    })

  }

  return (

          <div>
            {categories_all.map(item => (
              <label key={item.cat_key}>
                {item.label}{" "}
                <Checkbox
                  name={item.id} // I need the id not the name
                  checked={checkedItems[item.id]}
                  value={item.value}
                  onChange={handleCheckChange}
                />{" "}
              </label>
            ))}
          </div>
        )}
 

if I console.log(checkedItems) I get this:

{2: false, 3: true, 4: true} // this is just the id not the name

I would like to get something like:

{3, 4} 

To insert into a table

How can I do it?

4 Answers 4

1

Assuming the final output you get prior to submitting your form is an object that looks like the following:

{ 2: false, 3: true, 4: true }

You could use Object.entries to iterate through key/value pairs inside that object and only return keys with values that are true:

const formData = {2: false, 3: true, 4: true}

// use `Array.reduce` to iterate through
// object's key/value pairs
const final = Object.entries(formData).reduce(
  (accumulator, entry) => {
    // use destructing assignment to 
    // unpack key & value from an entry
    const [key, value] = entry;
    
    // if `value` is `false`, don't append
    // to the array, otherwise append the key
    if (!value) {
      return accumulator;
    }
    return [...accumulator, parseInt(key, 10)];
  }
, []);

console.log(final);

References:

Sign up to request clarification or add additional context in comments.

Comments

1

Loop over the entries of an object and check if the value is true, your code should look something like that:

let items = {2: false, 3: true, 4: true}
let checkedItems = {}; 
for (const [key, value] of Object.entries(items)) { 
    if (value === true) checkedItems[key] = key; 
}
console.log(checkedItems); /* {3: "3", 4: "4"} */

1 Comment

thanks, but it doesn't work, I chose another solution
0

Do you really need to keep track of unchecked values ?

If not, you probably need to change the data structure to make checkedItems and array containing the names of checked elements :

const [checkedItems, setCheckedItems] = useState([])

const handleCheckChange = (event) => {
  if (event.target.checked) {
    setCheckedItems((prev) => prev.concat(event.target.name));
  } else {
    setCheckedItems((prev) => prev.filter((current) => current !== event.target.name));
  }
};

This way, checkedItems only contains checked items (seems fair to me) and you can directly send it to your database.

Comments

0

Check boxes aren't meant to have True/false values. When you check a checkbox, it's value is added to the Form collection. Unchecking it removes it.

The right solution is to make the checkbox's value the Id of the thing you want to insert. On the server side, you will only see the selected ID's.

Although a more useful solution is to perform the selected/not selected check on the server to determine which previously selected things you should remove, in addition to which you should add. It's a more complete and robust solution than simply working with fresh inserts.

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.