Search code examples
vue.jsvuejs3pinia

cannot remove items from cart in vue 3 with pinia


so in the console log it is saying it is being removed from the cart but i can still see the items in the cart... how can i remove them from the cart? im using pinia for state management and the cart is in the state. why it is not working for me?

the code:

shop.vue

<template>
  <div class="shop">
    Cart Items: <cart-badge :count="cartLength">{{ count }}</cart-badge>
    <h1>shop</h1>
    <div class="products" v-for="item in Products" :key="item.id">
      {{ item.name }} {{ item.price }}$
      <button @click="storeCounter.addToCart(item)">Add to Cart</button>
    </div>
  </div>
</template>
<script setup>
import { useCounterStore } from "../stores/counter";
import Products from "../db.json";
import CartBadge from "../components/CartBadge.vue";
import { computed } from "vue";

const storeCounter = useCounterStore();

const cartLength = computed(() => {
  return storeCounter.cart.length;
});
</script>

store.js(pinia)

import { defineStore } from "pinia";

export const useCounterStore = defineStore("counter", {
  state: () => ({
    cart: [],
  }),
  actions: {
    addToCart(id) {
      this.cart.push(id);
      console.log("test passed!");
    },
    removeFromCart(id) {
      this.cart.splice(id);
      console.log("removed from cart!");
    },
  },
});

cart.vue

<template>
    <div class="cart">
        <h1>cart</h1>
        <div class="cartitems" v-for="item in storeCounter.cart" :key="item.id">{{ item.name }} {{ item.price }}$
        <button @click="storeCounter.removeFromCart(item.id)">X</button>
        </div>
    </div>
</template>

<script setup>
import { useCounterStore } from '../stores/counter';

const storeCounter = useCounterStore()

</script>

Solution

  • Splice uses the index of the item to delete it.

    Do this instead;

    removeFromCart(id) {
        let cartItemIndex = this.cart.findIndex(x => x.id === id);
    
        if (cartItemIndex >= 0) {
            this.cart.splice(cartItemIndex, 1);
            console.log("Removed from cart");
        }
    }
    

    or if you don't want to use splice anymore (and if performance matters);

    removeFromCart(id) {
        this.cart = this.cart.filter(x => x.id !== id);
        console.log("Removed from cart");
    }
    

    Please use more descriptive parameter names. Rename "id" to "item" in addToCart, since you're not just adding the item id, but the entire item. This can be confusing to other developers and make your code unreadable.

    addToCart(item) {
        this.cart.push(item)
        console.log('test passed!')
    }
    

    References: splice filter