skip to Main Content

I’m creating a shopping cart and when I want to add an element to the cart it adds the name and quantity just as many times as I click the add button, but what I want is the name added only one time and just the quantity increased as I click the add button. I can’t use inbuilt methods. I have try many ways but I can’t figure how to do it. Any idea? I think it must be very simple but can’t solve it.

So what I get now is this:

[ "geranios1", "geranios2", "rosas1", "rosas2", "ranunculos1", "geranios3", "calatheas1", "singonios1" ]

And what I want is this:

geranios: 3

rosas: 1

ranunculos: 4

This is my code:

      <button @click="mostrarLista(objeto.nombrePlanta)"

      const app=new Vue({
        el: '#app',
        data: {
            
            listaFlores: [],
            plantasAgregar:[
                {nombrePlanta: 'rosas', cantidad: 0, stock: 5},
                {nombrePlanta: 'ranunculos', cantidad: 0, stock: 3},
                {nombrePlanta: 'geranios', cantidad: 0, stock: 4},
                {nombrePlanta: 'calatheas', cantidad: 0, stock: 1},
                {nombrePlanta: 'singonios', cantidad: 0, stock: 2}
        ]
        },


         mostrarLista(florPlant){
                for(cosa of this.plantasAgregar){
                  if(cosa.nombrePlanta == florPlant && cosa.nombrePlanta !== this.listaFlores) 
         {
                        this.listaFlores.push(cosa.nombrePlanta + cosa.cantidad);
                        console.log(this.listaFlores);
                  }
               }        
            }

2

Answers


  1. The line of

    this.listaFlores.push(cosa.nombrePlanta + cosa.cantidad);
    

    pushes the name concatenated with the number. You will need to find the index of the element and increment its quantity, or, if such an index does not exist, then push it.

    Example

            let plantasAgregar = [
                    {nombrePlanta: 'rosas', cantidad: 0, stock: 5},
                    {nombrePlanta: 'ranunculos', cantidad: 0, stock: 3},
                    {nombrePlanta: 'geranios', cantidad: 0, stock: 4},
                    {nombrePlanta: 'calatheas', cantidad: 0, stock: 1},
                    {nombrePlanta: 'singonios', cantidad: 0, stock: 2}
            ];
            
            let cart = [];
            
            function add() {
                let item = document.getElementById("foo").value;
                let filtered = cart.filter((v) => v.nombrePlanta === item);
                if (filtered.length) {
                    cart[cart.indexOf(filtered[0])].cantidad++;
                } else {
                    cart.push({
                        nombrePlanta: item,
                        cantidad: 1
                    });
                }
                console.log(JSON.stringify(cart));
            }
    <select id="foo">
        <option value="rosas">rosas</option>
        <option value="ranunculos">ranunculos</option>
        <option value="geranios">geranios</option>
        <option value="calatheas">calatheas</option>
        <option value="singonios">singonios</option>
    </select>
    <input type="button" value="Add to cart" onclick="add()">
    Login or Signup to reply.
  2. The simple answer is to push an object to the cart array instead of a string so that you can track and display quantity of items.

    To do this you can create a reactive array for each of plantasAgregar and cart and use the function called on the add to cart click to update both (add to cart, increase quantity if existing, and reduce stock in plantasAgregar). Find the index of the selected product in either array and, based on whether it exists or not, update the item in the cart or push a new entry.

    The solution below uses the Composition API but should translate to the Options fairly easily, happy to help if you get stuck.

    <template>
      <select ref="productSelect">
        <option
          v-for="product in plantasAgregar"
          :key="product.nombrePlanta"
          :value="product.nombrePlanta"
        >
          {{ product.nombrePlanta }}
        </option>
      </select>
      <input
        type="button"
        value="Add to cart"
        @click="addToCart(productSelect.value)"
      />
    
      <ul v-for="item in cart">
        <li>{{ item.nombrePlanta }}: {{ item.cantidad }}</li>
      </ul>
    </template>
    
    <script setup>
    import { ref } from "vue";
    
    const productSelect = ref(null);
    
    const plantasAgregar = ref([
      { nombrePlanta: "rosas", cantidad: 0, stock: 5 },
      { nombrePlanta: "ranunculos", cantidad: 0, stock: 3 },
      { nombrePlanta: "geranios", cantidad: 0, stock: 4 },
      { nombrePlanta: "calatheas", cantidad: 0, stock: 1 },
      { nombrePlanta: "singonios", cantidad: 0, stock: 2 },
    ]);
    
    const cart = ref([]);
    
    const addToCart = (item) => {
      const productIndex = plantasAgregar.value.findIndex((product) => {
        return product.nombrePlanta === item;
      });
    
      const cartProductIndex = cart.value.findIndex((product) => {
        return product.nombrePlanta === item;
      });
    
      if (plantasAgregar.value[productIndex].stock > 0) {
        if (cartProductIndex >= 0) {
          plantasAgregar.value[productIndex].stock -= 1;
          cart.value[cartProductIndex].cantidad += 1;
        } else {
          const productToInsert = {
            nombrePlanta: plantasAgregar.value[productIndex].nombrePlanta,
            cantidad: 1,
          };
    
          cart.value.push(productToInsert);
          plantasAgregar.value[productIndex].stock -= 1;
        }
      } else {
        window.alert("No more items available.");
      }
    };
    </script>
    
    <style></style>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search