0

I am trying to have a single button that will add the value to the array, or if the value already exists in the array to remove that value.
The array is called toppings

const ToppingPlusMinus = (e) => {
  if (toppings.includes(e.target.value, 1)) {
    removeTopping(e)
  }
  else {
    changeToppings(e);
  }
}

The two functions

const removeTopping = (e) => {
  toppings.splice(e.target.value)
}

const changeToppings = (e) => {
    setToppings([...toppings, e.target.value]);
  };

The buttons are toppings on a pizza, and they are in this format

<button
            type="button"
            value="Sausage, "
            className="button btn first"
            onClick={(event) => {
              ToppingPlusMinus(event);
            }}
          >
            Sausage
          </button>

This works fine for adding the value to the array, however on removal there are unexpected outcomes.

  1. the item only is removed after the user double clicks the button
  2. the removal also removes the topping before it in the array.
  3. the button does not stay in its active state while the item is in the array (I haven't attempted this, but if anyone know how to do it I'd be appreciative)


I have set up a codesandbox with my code here I appreciate your help.

Dani Mesejo
  • 43,691
  • 6
  • 29
  • 53
imstupidpleasehelp
  • 710
  • 1
  • 3
  • 18

3 Answers3

1

First, the .includes doesn't need the second argument. toppings.includes(e.target.value) should be sufficient.

Second, you should define the remove function like this:

const removeTopping = (e) => {
  setToppings((toppings) => {
    return toppings.filter(topping => topping !== e.target.value)
  })
}

This should result in setting your toppings array with a new array that doesn't contain the selected value. You can also pass the value directly to your removeTopping and changeToppings functions.

1

I have made a working example on this code sandbox, so please check it!

The main reason your code doesn't work is the usage of toppings.splice(e.target.value) as here you are trying to directly modify the state without following the proper flow of setting it. So you would need to filter it out properly.

In my example, I used a different approach for the values, but the logic for removing them could remain the same with your approach too.

Renan Souza
  • 775
  • 5
  • 23
1

So basically you have array of items and you want to remove item if it exist.

This is vanilla js solution:

let toppings = []; // this will hold the topping 
const ToppingPlusMinus = (e) => {    // this will trigger on click
    if (toppings.indexOf(e.target.value) > -1) { // if the value of the button exist:
        removeA(toppings, e.target.value);     // remove it
    }
    else {
        toppings.push(e.target.value); // add it to the array
    };
    document.querySelector('#toppings').textContent = toppings.toString(); // this for demo
};

function removeA(arr) {
// https://stackoverflow.com/a/3955096/6525081
    var what, a = arguments, L = a.length, ax;
    while (L > 1 && arr.length) {
        what = a[--L];
        while ((ax= arr.indexOf(what)) !== -1) {
            arr.splice(ax, 1);
        }
    }
    return arr;
}
#toppings {font-size: larger;}
<button type="button" value="Sausage" className="button btn first" onClick="ToppingPlusMinus(event)">Sausage</button>
<button type="button" value="onion" className="button btn first" onClick="ToppingPlusMinus(event)">Onion</button>
<button type="button" value="olive" className="button btn first" onClick="ToppingPlusMinus(event)">Olive</button>

<div id="toppings"></div>
A. Meshu
  • 3,326
  • 2
  • 15
  • 29