I have a very strange problem in vue.js/axios.
Scenario 1 : clear my products variable BEFORE send an HTTP request (see "<<<<< SCENARIO 1" mark). Then set products variable with a new array. It works but we see a flicker (due to the HTTP request duration). So I decided to clear the products variable IN the request.
Scenario 2 : clear my products variable IN the HTTP request. (see "<<<<< SCENARIO 2" mark).
But I don't know why in Scenario 2 : my products variable is modified but the View don't change ! So my product variable has 3 products with related quantity. Then quantity of one product change so I clear the product variable and refresh with the HTTP request. All is the same but quantity of 1 product has changed. But the view don't reflect this !
let Cart = {
components: { Product },
data: function() {
return {
products: []
}
},
template: "<div><h3>Cart:</h3>" +
'<product @productChanged="updateProductsCart(product)"' +
'style="display: inline-block; max-width: 90px;" v-for="product in products"' +
':id="product.id" :name="product.name" :priceWithCurrency="product.priceWithCurrency"' +
':initQuantity="product.initQuantity" :picture="product.picture" :hasDeletedBtn="true"' +
':isProductRefreshAuto="false"></product>' +
"</div>",
methods: {
getAllProducts: function () {
let $this = this;
$this.clearProductsList();<<<<< SCENARIO 1
tdtdapi.get( '/cart/products/me', configs
).then(function (response) {
$this.clearProductsList();<<<<< SCENARIO 2
console.log("getAllProducts.then >")
console.log(response)
let products = [];
for( let i = 0, l = response.data.length; i < l; i++ ){
let product = response.data[i],
productToAdd = {
"name": "Product ",//todo delete raw value
"priceWithCurrency": 45
};
//todo: create a class Product
for( let prop in product ){
if( prop === "product" ) productToAdd.id = product[prop];
if( prop === "name" ) productToAdd.name = product[prop];
if( prop === "quantity" ) productToAdd.initQuantity = product[prop];
// if( prop === "description" ) productToAdd.description = product[prop];
if( prop === "price" ) productToAdd.priceWithCurrency = product[prop];
if( prop === "picture" ) productToAdd.picture = product[prop];
}
products.push(productToAdd);
}
$this.setProducts(products);
}).catch(function (error) {
console.log(error);
});
},
updateProductsCart: function( product ) {
console.log("updateProductsCart >")
console.log(product)
this.getAllProducts();
},
setProducts: function(products) {
console.log("setProducts >")
console.log(products)
this.products = products;
console.log(this.products)
},
clearProductsList: function() {
this.products.splice( 0, this.products.length );
}
},
mounted() {
this.getAllProducts();
},
computed: {
}
};
var app = new Vue({
el: "#app",
components: {
"ProductsList": ProductsList,
"Cart": Cart
}
});
There is the Product component if that help :
let Product = {
data() {
return {
quantity: this.initQuantity,
price: this.getPriceWithoutSymbols()
}
},
props: {
id: { type: Number, required: true },
name: { type: String, required: true },
description: { type: String, default: "" },
priceWithCurrency: { type: Number, required: true },
initQuantity: { type: Number, default: 0 },
picture: { type: String, default: "" },
hasDeletedBtn: { type: Boolean, default: false },
isProductRefreshAuto: { type: Boolean, default: true }
},
template: '<article :id="id">' +
'<div>{{ name }}</div>' +
'<div>{{ description }}</div>' +
'<div>{{ price }}</div>' +
'<div><img :src="picture"/></div>' +
'<div>Quantity: {{ quantity }}</div>' +
'<div>Total for this product: {{ totalPrice }}</div>' +
'<div>' +
'<button @click="decrementQuantity" type="button">-</button>' +
'<button @click="incrementQuantity" type="button">+</button>' +
'<br /><button v-if="hasDeletedBtn" @click="deleteProductQuantity" type="button">Delete product</button>' +
'</div>' +
'</article>',
methods: {
addQuantity( valueToAdd ){
//if quantity 0 to 1 ==> post
if( (this.quantity === 0) && (valueToAdd >= 1) ){
this.postProductQuantity(valueToAdd);
}
//if quantity 1 to 0 ==> delete
else if( (this.quantity === 1) && (valueToAdd === -1) ){
this.deleteProductQuantity();
}
//else ==> put
else{
this.putProductQuantity(valueToAdd);
}
},
postProductQuantity(valueToAdd){
console.log("POST")
let $this = this;
tdtdapi.post( '/cart/products/me', querystring.stringify({
product: $this.id,
quantity: valueToAdd
}), configs
).then(function (response) {
console.log(response);
$this.setQuantity(response.data.quantity);
}).catch(function (error) {
console.log(error);
});
},
putProductQuantity(valueToAdd){
console.log("PUT")
let $this = this;
tdtdapi.put( '/cart/products/me', querystring.stringify({
product: $this.id,
quantity: ($this.quantity + valueToAdd)
}), configs
).then(function (response) {
console.log(response);
$this.setQuantity(response.data.quantity);
}).catch(function (error) {
console.log(error);
});
},
deleteProductQuantity(){
console.log("DELETE")
let $this = this;
tdtdapi.delete( '/cart/products/me/' + this.id, configs
).then(function (response) {
console.log(response);
$this.setQuantity(0);//todo: use v-show to hide product when (this.quantity === 0)
}).catch(function (error) {
console.log(error);
});
},
emitChanged() {
this.$emit( "productChanged" );
},
incrementQuantity(){
this.addQuantity(1);
},
decrementQuantity( product ){
console.log(product)
// if( this.quantity >= 1 ){
// this.addQuantity(-1);
// }
},
getPriceWithoutSymbols(){
//todo: if price contains currency, when need to get only the value
return this.priceWithCurrency;
},
setQuantity( quantity ){
if( this.isProductRefreshAuto ){
this.quantity = quantity;
}
this.emitChanged();
}
},
computed: {
totalPrice: function(){
return (this.quantity * this.price).toFixed(2);
}
}
};