Search code examples
javascriptarraysvue.jsvuex

Splice not splicing from the index its being given?


Working in vue here, specifically vuex although it's likely a vanilla js problem. I've got a cart setup that pushes from a product list to a shopping cart on button press, but I cannot get deleting from the cart to work. Here's my approach;

The child calling the action from a button;

<b-button @click="removeItem" variant="primary">Remove from Cart</b-button>

data() {
    return {
        singleCart: this.items,
    };
},
methods: {
    removeItem() {
        this.$store.dispatch("DELETE_CART_ITEM", this.singleCart.item_id);
    },
},

And the logic in my vuex store;

const actions = {
    ADD_TO_CART: (context, payload) => {
        context.commit('MUTATE_CART', payload)
    },
    DELETE_CART_ITEM: (context, payload) => {
        context.commit('DELETE_FROM_CART', payload)
    }
}

const mutations = {
    MUTATE_CART: (state, item) => {
        state.cart.push(item)
    },
    DELETE_FROM_CART: (state, payload) => {
        //filter the array for the item id, then splice it?

        console.log(payload)

        var index = state.cart.findIndex(item => item.item_id === payload)

        console.log(index)

        console.log(typeof index)

        state.cart.splice(index, 1)
    }
}

All my logging shows the correct payload, and the correct index of the item in the cart, but when the splicing happens, It's removing the last item on the list, even though its being passed a starting index.

For example if I have 3 items in the cart, and I want to remove the second, it finds the proper index, 1 in such case, logs it to be sure, then for whatever reason splice deletes the last item on the list. Why? And what would I do to fix this?

SOLUTION: Turns out I was just confused on how I should call my getter data in the end, the solution was in the parent component that loops over the shopping cart items and using a computed property to get it instead as such;

<div v-for="item in cart" :key="item.id">
<cartProduct :items="item" />
</div>

computed: {
    cart() {
        return this.$store.getters.GET_CART 
    }
},

And thus was reactive.


Solution

  • This is a weird Vue caveat. Below is an example of what will not work in this case.

    DELETE_FROM_CART: (state, payload) => {
            var index = state.cart.findIndex(item => item.item_id === payload);
            var dummy = state.cart.slice();
            dummy.splice(index, 1);
            state.cart = dummy;
        }