Search code examples
javascriptvue.jsvuejs2vuexstore

add multiple Payloads on Vuex


I would like to pass 2 data, amount and id to the store so i try to give 2 payloads on the Actions but it doesn't work. Both data are undefined

How to pass 2 payloads in the same event ? (you can find that where the console.logs are)

When i put one single payload (id or amount, i got the correct value, but not when i try to give 2 payloads.

Thanks in advance!

Here my component :

    <script>
import { mapActions } from 'vuex'
import BaseButton from './BaseButton.vue'

export default {

  name: 'MenuItem',
  components: {
    BaseButton
  },
  props: {
    image: {
      type: Object,
      required: true
    },
    inStock: {
      type: Boolean,
      required: true
    },
    name: {
      type: String,
      required: true
    },
    price: {
      type: Number,
      required: true
    },
    quantity: {
      type: Number,
      defaut: 1
    },
    id: {
      type: Number,
      defaut: 1
    }
  },
  data() {
    return {
      onSale: false
    }
  },
  computed: {
    generatedPrice() {
      if (this.onSale) {
        return (this.price * 0.9).toFixed(2)
      } else {
        return this.price
      }
    }
  },
  methods: {
    ...mapActions(['updateShoppingCart'])
  },
  beforeMount() {
    const today = new Date().getDate()

    if (today % 2 === 0) {
      this.onSale = true
    }
  }
}

</script>

<template>
  <div class="menu-item">
    <img class="menu-item__image" :src="image.source" :alt="image.alt" />
    <div>
      <h3>{{ name }}</h3>
      id : {{ id }}
      <p>Price: {{ generatedPrice }} <span v-if="onSale">(10% off!)</span></p>
      <p v-if="inStock">In Stock</p>
      <p v-else>Out of Stock</p>
      <div>
        <label for="add-item-quantity">Quantity: {{ quantity }}</label>
        <input v-model.number="quantity" id="add-item-quantity" type="number" />
        <BaseButton @click="updateShoppingCart(quantity, id)" class="test">
          Add to shopping cart
        </BaseButton>
      </div>
    </div>
  </div>
</template>

here the store :

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    restaurantName: 'Cafe with A Vue',
    shoppingCart: 0,
    selectedItemId: 0,
    croissiantNumber: 0,
    baguetteNumber: 0,
    eclairNumber: 0,
    simpleMenu: [
      {
        id: 1,
        name: 'Crossiant',
        image: {
          source: '/images/crossiant.jp',
          alt: 'A crossiant'
        },
        inStock: true,
        quantity: 1,
        price: 2.99
      },
      {
        id: 2,
        name: 'French Baguette',
        image: {
          source: '/images/french-baguette.jpe',
          alt: 'Four French Baguettes'
        },
        inStock: true,
        quantity: 1,
        price: 3.99
      },
      {
        id: 3,
        name: 'Éclair',
        image: {
          source: '/images/eclair.jp',
          alt: 'Chocolate Éclair'
        },
        inStock: false,
        quantity: 1,
        price: 4.99
      }
    ]
  },
  getters: {
    copyright: state => {
      const currentYear = new Date().getFullYear()

      return `Copyright ${state.restaurantName} ${currentYear}`
    }
  },
  mutations: {
    ADD_ITEMS_TO_TOTAL_SHOPPING_CART(state, {amount}) {
      state.shoppingCart += amount
    }
  },
  actions: {
    updateShoppingCart({ commit }, {amount, id}) {
      commit('ADD_ITEMS_TO_TOTAL_SHOPPING_CART', {amount, id})
      console.log(id)
      console.log(amount)
    }
  },
  modules: {}
})

Solution

  • Question 1

    Your action expects an object with 2 properties: amount and id. But you are not passing an object, but rather two separate variables updateShoppingCart(quantity, id).

    In your template, call it like this instead:

    updateShoppingCart({ amount: quantity, id });  // Note the object brackets
    

    Or, rename quantity in your component to amount and you could call it like this:

    updateShoppingCart({ amount, id });
    

    Question 2 (using destructuring)

    mutation:

    ADD_ITEMS_TO_TOTAL_SHOPPING_CART(state, { amount, id }) {
      state.shoppingCart += amount;
      console.log(id);
    }
    

    action:

    updateShoppingCart({ commit }, { amount, id }) {
      commit('ADD_ITEMS_TO_TOTAL_SHOPPING_CART', { amount, id })
      console.log(id)
      console.log(amount)
    }
    

    Question 2b (alternative using payload):

    mutation:

    ADD_ITEMS_TO_TOTAL_SHOPPING_CART(state, payload) {
      state.shoppingCart += payload.amount;
      console.log(payload.id);
    }
    

    action:

    updateShoppingCart({ commit }, payload) {
      commit('ADD_ITEMS_TO_TOTAL_SHOPPING_CART', payload)
      console.log(payload.id)
      console.log(payload.amount)
    }