Vue/ Nuxt - run code after the entire view has been rendered? - vue.js

I want to create a few functions after after the entire view has been rendered / mounted:
export default {
mounted: function () {
this.example = function() {
return 'example'
},
function() {
console.log('mounted') // does not work
}
},
created () {
console.log(this.example()) // error
},
methods: {
submitMessage() {
console.log(this.example()) // example
}
}
}
Why do I get the error below at created()?
TypeError: this.example is not a function
at VueComponent.created (index.vue:119)
at callHook (vue.runtime.esm.js:2661)
at VueComponent.Vue._init (vue.runtime.esm.js:4222)
at VueComponent (vue.runtime.esm.js:4392)
at createComponentInstanceForVnode (vue.runtime.esm.js:3674)
at init (vue.runtime.esm.js:3491)
at createComponent (vue.runtime.esm.js:5143)
at createElm (vue.runtime.esm.js:5086)
at VueComponent.patch [as __patch__] (vue.runtime.esm.js:5602)
at VueComponent.Vue._update (vue.runtime.esm.js:2420)
Any ideas?

The created hook is called before the mounted hook. When the created() function runs, this.example has not yet been declared.
You will be able to call this.created() after it has been declared.
Refer to the lifecycle diagram.

Related

Nuxt - How to call a getters in a global mixins?

Hi everyone here is the mixin code I wrote as I want to use this for default.vue and error.vue layout. I am trying to avoid duplicating code in two layout.
export default {
provide () {
return {
copyRight: this.getCopyrightText,
email: this.getEmail,
socials: this.getSocials
}
},
computed: {
getMenu () {
return this.store.getters['general/getMenu'].menu
},
getSocials () {
return this.store.getters['general/getSocialDetails']
},
getCopyrightText () {
return this.store.getters['general/getCopyRight']
},
getEmail () {
return this.store.getters['general/getEmail']
}
},
middleware: 'load-menu-items'
}
This is what I get: Cannot read property 'length' of undefined
What am I doing wrong?
In your component I assume you're using .length on the data you're receiving from the getter method, which is probably where the error occurs.
First of all you should debug to see if your getter is actually working as expected. Try this and look at output in console for every getter computed property. If undefined is printed to the console you'll get the error you posted if you're using .length on it
getEmail () {
let data = this.store.getters['general/getEmail'];
console.log(data);
return data;
}
If you post the component which is using this mixin maybe I can help you further.

VueJS | Method "watch" has type "object" in the component definition

Currently I have following Watches in Product.vue file
watch: {
isOnline: {
async handler (isOnline) {
if (isOnline) {
const maxQuantity = await this.getQuantity();
this.maxQuantity = maxQuantity;
}
}
},
isMicrocartOpen: {
async handler (isOpen) {
if (isOpen) {
const maxQuantity = await this.getQuantity();
this.maxQuantity = maxQuantity;
}
},
immediate: true
},
isSample (curr, old) {
if (curr !== old) {
if (!curr) {
console.log('send the updateCall', curr);
// this.updateProductQty(this.product.qty);
pullCartSync(this);
}
}
}
}
but I am getting this following error (Vue Warn) in console
[Vue warn]: Method "watch" has type "object" in the component definition. Did you reference the function correctly?
I'm not sure why i am getting this error, as the syntax i am using seems to be correct, and its even functioning right.
Any suggestions why its giving this warning in error console?
Update:
Location where i have used the watch in vue page.
You have something like methods: { watch: {} } in your component definition. That's why vue is complaining. That might be added by a mixin as well.

How can I fill an array by calling a method in Vue js?

I am trying to fill an array, declared in data property, by calling a function in methods property in Vue js. Here is the code:
<script>
export default {
extends: Bar,
mounted() {
this.renderChart(this.chartData, this.options);
this.fillLabel();
},
data() {
return {
chartData: {
labels:[],
datasets: [
{
label: "Users",
data: [40,20,12,39,10,40]
}
]
},
};
},
methods: {
fillLabel() {
this.chartData.datasets[0].data.map(function (key,value) {
this.chartData.labels.push(key);
})
}
}
};
</script>
But this gives me following error in console :
[Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'chartData' of undefined"
So how can I fill the labels array(inside chatData) by 0 to length of data array(inside datasets).
I am looking for your help. Thanks in advance.
This is due to the fact that your function inside your map function will loose the this context. and so its getting undefined.
to solve this problem use an arrow function inside your map.
this.chartData.datasets[0].data.map((key,value)=> {
this.chartData.labels.push(key);
})
this will solve the problem
Only need to introduce this to your fillLabel method as below:
I tried this solution nd it fixed the problem
fillLabel() {
let th = this;
th.chartData.datasets[0].data.map(function (key,value) {
th.chartData.labels.push(key);
})
alert(th.chartData.labels)
},

Computed property that depends on another computed property

Code below yields error "Cannot read property 'form' of undefined":
computed: {
boundary_limits () {
return this.$refs.hemoBoundaryLimits.form;
},
high_risk_alerts () {
return this.$refs.highRiskAlerts.form;
},
alerts () {
return {
boundary_limits: this.boundary_limits,
high_risk_alerts: this.high_risk_alerts
}
}
}
Yet if I removed alerts(), I get no error and I can even console log boundary_limits or high_risk_alerts
successfully, which means $refs.hemoBoundaryLimits and this.$refs.highRiskAlerts are defined.
So Vue.js has a problem with how I define alerts, but I see no problem in it.
Any clue what's going on?
The error comes because you are trying to access $refs in computed property.
Computed properties are evaluated before the template is mounted and thus the hemoBoundaryLimits is undefined.
You should access $refs in the mounted hook.
As solution, you can trick it by knowing when the component is mounted using #hook event:
<hemoBoundaryLimits #hook:mounted="isHemoBoundaryLimitsMounted = true" />
And in the script
data: () => ({
isHemoBoundaryLimitsMounted: false
}),
computed: {
boundary_limits () {
if (!this.isHemoBoundaryLimitsMounted) return
return this.$refs.hemoBoundaryLimits.form;
}
}

Vue initializing props to data for mutation but Error in data(): "TypeError: Cannot read property 'propsTitle' of undefined"

Error in data(): "TypeError: Cannot read property 'propsTitle' of undefined"
I cant initialize by props to data. it keeps showing me this error and I can't figure it out why? I read the vuejs tutorial it shows title: this.propsTitle this is the correct way. what am I missing? Thank everyone!
Error in data(): "TypeError: Cannot read property 'propsTitle' of
undefined"
props: {
propsTitle: String,
propsLevel: Number,
propsProgress: Number,
},
data: () => ({
title: this.propsTitle,
progress: this.propsLevel,
level: this.propsLevel,
activeBtnTxt: "Start",
isStarted: false
}),
// watch: {
// progress(val) {
// this.progress = val
// }
// },
// mounted() {
// console.log(this.propsProgress)
// // this.progress = propsProgress
// // this.level = propsLevel
// // this.title = propsTitle
// },
This:
data: () => ({
...
})
Should be this:
data () {
...
}
If you use an arrow function you'll end up with the this reference pointing at the wrong object.
There is a note about this in the docs: https://v2.vuejs.org/v2/api/#data
Note that if you use an arrow function with the data property, this won’t be the component’s instance...
Here is the corrected code. You have to use a function with return.
props: {
propsTitle: String,
propsLevel: Number,
propsProgress: Number,
},
data() {
console.log(this)
return {
title: this.propsTitle,
progress: this.propsProgress,
level: this.propsLevel,
activeBtnTxt: "Start",
isStarted: false
}
},