Reputation: 3258
I have a button that I'm rendering with a Vue component. The button depends on some async
data from the backend that controls its visibility. The data is being returned and updated fine. However, the button is not shown for some reason. I'm not sure if its because the DOM has already loaded? Not sure why I'm not seeing the button. I've tried both using a computed property as well as a simple data property and both don't work.
However, the console.log
IS showing the correct data at the correct time.
Plus if I just set displayLauncherButton
it displays fine.
EDIT: To clarify this is a component that gets inserted into an HTML document that was rendered with liquid.
Here is my simplified code:
Vue.component('fresh-credit', {
data: function () {
return {
creditAmount: '',
currencySymbol: '',
customerId: '',
displayLauncherButton: false,
}
},
mounted() {
this.getCustomerCredit
this.makeItShow
},
template:
`
<div :style="buttonContainer" v-if="makeItShow">
<button
:style="buttonStyle"
>You Have $</button>
</div>
`,
computed: {
makeItShow() {
console.log("this is returning " + this.displayLauncherButton)
return this.displayLauncherButton
},
buttonContainer() {
return {
position: 'fixed',
right: '10px',
top: '150px',
zIndex: '99999',
}
},
buttonStyle() {
return {
'border-radius': '4px',
'border': 'none',
'height': '44px',
'min-width': '78px',
'padding': '0 19.5555555556px',
'font-size': '14px',
'font-weight': 'bold',
'text-transform': 'uppercase',
'cursor': 'pointer',
'color': 'white',
'background-color': '#4D4D4DFF',
'box-shadow': '0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)!important',
'outline': 'none',
}
},
async getCustomerCredit() {
if(this.customerId) {
let response = await axios.post(`/apps/fresh_credit_proxy`, { shopify_customer_id: this.customerId, type: 'customer_credit'})
if(response.status == 200) {
if(response.data.customer_credit == 'no_credit') {
this.displayLauncherButton = false
return
}
else {
this.creditAmount = response.data.customer_credit.current_credit_balance
this.currencySymbol = response.data.customer_credit.current_credit_balance
this.displayLauncherButton = true
console.log("during get credit " + this.displayLauncherButton)
}
}
}
},
},
})
new Vue({ el: '#freshie' })
Upvotes: 0
Views: 1473
Reputation: 90013
computed
are getters.
This means that
mounted() {
this.getCustomerCredit
this.makeItShow
}
is equivalent to:
mounted() {
this.getCustomerCredit
false
}
... because makeItShow
gets the current value of displayLauncherButton
, which is false
in mounted
.
You probably want:
mounted() {
this.getCustomerCredit().then(() => {
console.log(this.makeItShow);
});
},
methods: {
// move if here from getters
async getCustomerCredit() {
/.../
}
}
Note that you don't need makeItShow
at all. It will always return the current value of displayLauncherButton
, so you can just use displayLauncherButton
instead.
If you want to run some effect whenever displayLauncherButton
changes, don't use a computed
, use a watch on displayLauncherButton
. For example, to log the value of displayLauncherButton
every time it changes, add:
watch: {
displayLauncherButton: console.log
}
to your component. This will log both parameters (newVal, oldVal)
, every time it changes.
Note the mounted
above can also be written as:
async mounted() {
await this.getCustomerCredit();
console.log(this.makeItShow)
}
Don't let async mounted
trick you into believing it will delay the rendering of the component. The component will render before mounted
returns if mounted
is async
.
Upvotes: 2