1

I have a simple cart store, to add / remove items.

When you add a product to the cart, I show a flash message with the possibility to update the quantity. Since I don't know which product is concerned in my flash message component, I use the store.

I have a simple bootstrap spinner :

    <b-form-spinbutton
      :value="value"
      min="1"
      max="26"
      @change="setItems"
    />

When I change this, I want to call the setItems function of my store to update the last item added.

So I used :

  data () {
    return {
      value: 1
    }
  },
  methods: {
    setItems (value) {
      const items = [...this.$store.getters['cart/items']]
      // update quantity of the last item - we suppose it's the current item
      items.slice(-1)[0].quantity = value
      this.$store.commit('cart/setItems', items)
    }
  }

I read about this error here : Vuex - Do not mutate vuex store state outside mutation handlers, so I changed v-model to value approach.

My store cart.js is :

export const state = () => ({
  items: []
})

export const mutations = {
  setItems (state, items) {
    state.items = items
  },
  // ....

I can't figure how to handle this problem ?

Vincent Decaux
  • 9,857
  • 6
  • 56
  • 84

1 Answers1

3

The line were the store state is mutated outside mutation handler is:

items.slice(-1)[0].quantity = value

By using spread operator you create a shallow copy of store items. each item property still references the vuex state. you can create a deep copy, with:

const items = JSON.parse(JSON.stringify(this.$store.getters['cart/items']))

Or, if you have lodash in your project:

const items = _.cloneDeep(this.$store.getters['cart/items'])
Igor Moraru
  • 7,089
  • 1
  • 12
  • 24
  • Oh ok ! because I tried other methods to clone my object using reduce or map I saw on internet, but your method clearly works and it was indeed this, thanks ! – Vincent Decaux Jun 19 '21 at 15:18
  • Lodash is recommended because of some rare issues with the stringify solution. – kissu Jun 19 '21 at 15:32