Chaim Friedman
Chaim Friedman

Reputation: 6263

V-model is not binding as expected

I have a table that iterates over a list of products. For each product in the table I have an input where the user can choose how many units he wants of the product in this row. Then I have another cell in the table for the total which is calculated based on the user quantity multiplied by the unit price. Here is my table.

         <table class="table table-striped table-borderd">
                <template v-for="(c, catIndex) in products">
                    <tr>
                        <th>{{c.category}}</th>
                        <th>{{c.bulkSize}}</th>
                        <th>Price</th>
                        <th>Quantity</th>
                        <th>Total</th>
                    </tr>
                    <tr v-for="(p, productIndex) in c.productList">
                        <td>{{p.description}}</td>
                        <td>{{p.productSize}}</td>
                        <td>{{p.productPrice}}</td>
                        <td>
                            <input v-on:keyup='calculateTotal(catIndex, productIndex)' type="text" v-model="p.quantity" placeholder="Quantity">
                        </td>
                        <td>
                            <input 
                            type="text"
                            readonly 
                            v-model="p.total">
                        </td>
                    </tr>
                </template>
            </table>

Then in my JavaScript I calculate the total on keyup. Here is the code.

calculateTotal: function(categoryIndex, productIndex) {
        let currentCategory = this.products[categoryIndex];
        let currentProduct = currentCategory.productList[productIndex];
        currentProduct.total = currentProduct.quantity * currentProduct.productPrice;
        console.log(this.products[categoryIndex].productList[productIndex].total);
    }

The console.log() shows me the correct value but the cell that is bound to total never updates.

I should point out, that both the quantity key, and the total key, are added to the product object through v-model.

Where am I going wrong?

EDIT: Based on answers below I added this code to try and fix the issue, but it did not work.

created: function() {
    $.get('some endpoint', data => {
        this.customers = data.customers;
        this.locations = data.locations;
        this.products = data.products;
        this.products.forEach(cat => {
            cat.productList.forEach(product => {
                product.total = undefined;
            })
        })
    });
},

Upvotes: 1

Views: 2161

Answers (2)

Lukasz Wiktor
Lukasz Wiktor

Reputation: 20422

You can fix it by adding total property to your products. It may be 0 or even undefined, however, it has to be there. It's by design. Related issues on github: https://github.com/vuejs/vue/issues/1797 and https://github.com/vuejs/vue/issues/3732.

Upvotes: 1

Marek Urbanowicz
Marek Urbanowicz

Reputation: 13674

Fixed: http://jsbin.com/nilutegexo/1/edit?html,js,console,output

It was caused by that you are creating list totally dynamically and it is causing issues with reactivity. You have to basically initiate total: 0 and it works perfectly fine.

Upvotes: 0

Related Questions