1

I have a react application and in that I have the following list of objects.

const orderItems = [
  {
    id: 1,
    name: "item 1",
    price: "100",
    availableQty: 2,
    out: ""
  },
  {
    id: 2,
    name: "item 2",
    price: "100",
    availableQty: 2,
    out: ""
  },
  {
    id: 3,
    name: "item 3",
    price: "100",
    availableQty: 2,
    out: ""
  },
  {
    id: 4,
    name: "item 4",
    price: "100",
    availableQty: 2,
    out: ""
  }
];

Im mapping through the orderItems list and display the name with a checkbox. I have a state named selectedItem and when the checkbox is checked, new object adds to the selectedItem along with the id of the orderItems as shown in the following code.

const handleSelect = (e, item) => {
    const { checked } = e.target;

    const newObj = {
      id: item.id,
      isAdded: true,
      reason: "",
      issue: "",
      availableStock: ""
    };

    if (checked) {
      setselectedItem((previousState) => [...previousState, newObj]);
    }
    if (checked === false) {
      const filteredItems = selectedItem.filter(
        (singleItem) => singleItem.id !== item.id
      );

      setselectedItem(filteredItems);
    }
  };

In the react app, Im mapping the orderItems and showing the name with a checkbox. When the checkbox is checked, I add a new object to selectedItem with the id of orderItems and if the selectedItem is empty, I display a as "list is empty". If checkbox is selected, I display a input tag under the name and if its not selected, i display a label with the text "not selected" as shown in the code below.

<div className="app">
      {items.map((item) => (
        <div className="issue">
          <input type="checkbox" onChange={(e) => handleSelect(e, item)} />
          <label>{item.name}</label>
          {selectedItem.length > 0 ? (
            <>
              {selectedItem.map((singleItem) =>
                singleItem.id === item.id ? (
                  <input type="number" />
                ) : (
                  <label>not selected</label>
                )
              )}
            </>
          ) : (
            "list is empty"
          )}
        </div>
      ))}
    </div>

The issue here is, when one item is checked, it show input tag under selected item and shows "not selected" label under other items but if i select two checkboxes, both not selected label and input tag displays. If i select 3 checkboxes, not selected label displays two times with input tag.

What i want is to display only the input tags under selected items and display not selected label under unchecked items.

codesandbox link: https://codesandbox.io/s/minsaf-2jjt2g

1 Answer 1

1

You are mapping the selectedItem array for every element in the item array. This means for any element in the array that some condition matches and both the input and label are rendered.

If I understand the code and your expected behavior I think you should conditionally render a single input or label based on if the selectedItem array includes an element matching by id.

Example:

<div className="app">
  {items.map((item) => (
    <div className="issue">
      <input type="checkbox" onChange={(e) => handleSelect(e, item)} />
      <label>{item.name}</label>
      {selectedItem.length ? (
        selectedItem.some((singleItem) => singleItem.id === item.id) ? (
          <input type="number" />
        ) : (
          <label>not selected</label>
        )
      ) : (
        "list is empty"
      )}
    </div>
  ))}
</div>

Edit how-to-compare-objects-of-two-different-arrays-in-javascript

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

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.