Reputation: 393
I have component, ShopCart.vue (code below), that is receiving props from the parent. One of those props is cartItems
. I am running a function on the cartItems in mounted()
but to make sure the props were ready, I put them in Vue.nextTick
, which I saw as a solution here on StackOverflow. That seemed to resolve the issue but I noticed it wasn't reliable and there were instances where the cartItems would be empty when the function was ready. To test this, I put them in a setTimeout for 3 seconds and then the cartItems had 20 passed items, so I know it's working..it's just running too quickly. How can I resolve this to ensure the props are ready in this component?
Part of the ShopCart.vue
export default {
data() {
return {
dataLoaded: false,
modalType: null,
orderNotes: null,
test: null,
expireTimes: {
}
}
},
props: {
cartItems: {type: Array},
cart: {type: Object},
customer: {type: Object}
},
mounted() {
let vm = this;
Vue.nextTick(() => {
vm.cartItems.forEach((item, index) => {
Vue.set(vm.expireTimes, item.item_id, "")
this.checkItemExpiry(item.expire_at, item.item_id)
});
});
}
Upvotes: 5
Views: 7607
Reputation: 1137
You could try using Vue's watch property over the cartItems
prop so when it changes you can then process it, like so:
watch: {
cartItems(newVal) {
newVal.forEach((item, index) => {
Vue.set(vm.expireTimes, item.item_id, "")
this.checkItemExpiry(item.expire_at, item.item_id)
});
}
}
Make sure to pass an empty array if the cartItems
is not ready in the parent component, or validate with something like if(newVal){ ... }
before the forEach
iteration.
Upvotes: 5
Reputation: 14211
Vue.nextTick is usually used when updating a reactive component and you want to use the DOM with the updated value. Vue.nextTick is not intended for async operations, as the time for the async operation is not known in advanced.
Your best bet is to use a v-if when disaplaying the content. This will also allow you to use v-else and maybe show a preloader.
Upvotes: 0
Reputation: 5632
@Francisco Hanna's answer will work for you, but you can avoid a watcher (which is consuming resources) if you simply use v-if
to render the shopCart
component only after any cartItems exist:
in the parent component:
<shop-cart :cartItems="cartItems" v-if="cartItems.length"></shop-cart>
Upvotes: 13