Search code examples
javascriptvue.jsvuex

Update DOM on Vuex store state change


I have an 'Add To Basket' button which triggers a Vuex store action:

<button
  @click="addToBasket(item)"
>
  Add To Basket
</button>

Vuex store:

const actions = {
    addToBasket({ commit }, item) {
        commit("setBasketItems", item);
    }
};

const mutations = {
    setBasketItems: (state, item) => {
        let basketFind = state.basket.find(i => {
            return i.id === item.id;
        });

        if (basketFind) {
            basketFind.quantity += 1;
            return;
        }

        item.quantity = 1;

        state.basket.push(item);
    }
};

const state = {
    basket: []
};

const getters = {
    basketItems: state => state.basket,
};

When I check the Vuex store in dev tools it's doing what it should, i.e adding the item if it doesn't exist, incrementing the quantity if it does.

I'm trying to update the DOM to display the item's quantity:

computed: {
  computedBasketItems: function() {
    return this.$store.getters.basketItems;
  }
},
<CartItem
  v-for="item in computedBasketItems"
  :key="item.id"
  :item="item"
/>

CartItem (accepting the item as a prop):

<div class="dropdown-item">
  <i class="fa fa-times-circle"></i>
  <router-link to="">{{ item.name }}</router-link>
  <p>{{ item.quantity }}x</p>
  <p>{{ item.price }}</p>
</div>

// props...
    props: ["item"],

It adds the item to the DOM and sets the quantity to '1' but doesn't update the quantity whenever it changes.

How can I do this?


Solution

  •   const mutations = {
        setBasketItems: (state, item) => {
          // in this line we checking if item id equal state backet item id it returns first matched element 
          let basketFind = state.basket.find((i) => {
            return i.id === item.id;
          });
    
          // here we checking if basketFind has value(aka array contains value) 
          if (basketFind) {
    
            // if basketFind is true in this case will be implement this block
            state.basket = state.basket.map((x) =>
              x.id === item.id ? { ...x, quantity: x.quantity + 1 } : x
            );
    
            // in this line we reassigning basket prop of state with transformed data
            // just checking if  x.id === item.id then increase matched element's prop quantity  
            // also we leave other elements which contains state.basket array
            return;
    
          }
          // if basketFind is false we going this line
          // again, reassigning basket prop of state. adding existing element and adding new element with value 1 of quantity prop
          state.basket = [
            ...state.basket,
            ...[item].map((x) => ({ ...x, quantity: 1 })),
          ];
        },
      };