renataedit
renataedit

Reputation: 33

Push to array with v-model

I'm new to Vue.js, and I'm trying to create a shop app with Vue & Webpack. I have some products in a json file, and rendering them with a v-for.

When clicking on Add to cart button, it should put the product number, and the selected quantity to an array.

How can I properly increase quantity for a specific product? So far I have the following:

<template>
  <div v-for="(product, index) in products" >
    <div><img :src="product.product_image" /></div>
    <div>
      <input type="number" min="0" v-model="qty[index]" />
      <button @click="addToCart(product.id, qty[index])">Add to cart</button>
    </div>
  </div>
</template>


<script>

  import productList from '../products.json';

  export default{
    name: 'shop',
    data(){
      return {
        products: productList,
        cartElements: [],
        qty: [],
      }
    },
    props: [ 'itemsInCart' ],
    methods:{
      addToCart(product_id, quantity){
        this.cartElements.push( {
          "id" : product_id,
          "quantity" : quantity,
        } );
        console.log(this.cartElements);
      },
    },
  }
</script>

The result is ok, but the input fields are acting weird.

e.g. If I increase the third product's input, it sets the first and second product input to 1, and only then sets the third input to the desired number.

Upvotes: 3

Views: 7399

Answers (2)

andresgottlieb
andresgottlieb

Reputation: 950

You are expecting qty = [] to be automatically populated by the v-model directive. Try initializing that array yourself using vuejs' created function, like this:

<template>
<div v-for="(product, index) in products" >
    <div><img :src="product.product_image" /></div>
    <div>
        <input type="number" min="0" v-model="qty[index]" />
        <button @click="addToCart(product.id, qty[index])">Add to cart</button>
    </div>
</div>
</template>
    
    
<script>
import productList from '../products.json';
export default{
    name: 'shop',
    data(){
        return {
            products: productList,
            cartElements: [],
            qty: [],
        }
    },
    props: [ 'itemsInCart' ],
    methods:{
        addToCart(product_id, quantity){
            this.cartElements.push( {
                id" : product_id,
                quantity" : quantity,
            });
            console.log(this.cartElements);
        },
    },
    created: function () {
        var i = 0;
        for (i = 0; i < this.products.length; i++){
            this.$set(this.qty, i , 0) // This is the vuejs-way of setting array values
        }
    }
}
</script>

Upvotes: 3

renataedit
renataedit

Reputation: 33

So with andresgottlieb's help, my final code looks like this:

<template>
<div v-for="(product, index) in products" >
    <div><img :src="product.product_image" /></div>
    <div>
        <input type="number" min="0" v-model="qty[index]" />
        <button @click="addToCart(product.id, qty[index])">Add to cart</button>
    </div>
</div>
</template>


<script>
import productList from '../products.json';
export default{
    name: 'shop',
    data(){
        return {
            products: productList,
            cartElements: [],
            qty: [],
        }
    },
    props: [ 'itemsInCart' ],
    methods:{
        addToCart(product_id, quantity){
            this.cartElements.push( {
                "id" : product_id,
                "quantity" : quantity,
            } );
            console.log(this.cartElements);
        },
    },
    created() {
        var i = 0;
        for (i = 0; i < this.products.length; i++){
            this.$set(this.qty, i, 0) // This is the vuejs-way of setting array values
        }
    }
}
</script>

Upvotes: 0

Related Questions