i am a beginner in Vue.js so maybe i made a stupid mistake but i honestly don't understand why do i got such an error... can you help me please? here is a code: Javascript:
const bootstrap = require("./assets/bootstrap.png");
const bulma = require("./assets/bulma.png");
const css3 = require("./assets/css3.png");
const html5 = require("./assets/html5.png");
const illustrator = require("./assets/illustrator.png");
const js = require("./assets/js.png");
const photoshop = require("./assets/photoshop.png");
const vue = require("./assets/vue.png");
const webpack = require("./assets/webpack.png");
export default {
name: "app",
data() {
return {
images: [
bulma,
bootstrap,
css3,
html5,
illustrator,
js,
photoshop,
vue,
webpack
],
idx: Math.floor(Math.random() * this.images.length),
randomImage: this.images[this.idx]
};
}
};
and HTML:
<div id="app">
<div id="myContainer">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view />
<button v-on:click="animate">Test</button>
<img v-for="image in images" :src="image" />
</div>
</div>
Error in data(): "TypeError: Cannot read property 'length' of undefined" (Vue.js)!!! problem is connected with Math.floor(Math.random() * this.images.length) as i understand. In future i want to use randomPicture to generate random pictures.
i am a beginner in Vue.js so maybe i made a stupid mistake but i honestly don't understand why do i got such an error... can you help me please? here is a code: Javascript:
const bootstrap = require("./assets/bootstrap.png");
const bulma = require("./assets/bulma.png");
const css3 = require("./assets/css3.png");
const html5 = require("./assets/html5.png");
const illustrator = require("./assets/illustrator.png");
const js = require("./assets/js.png");
const photoshop = require("./assets/photoshop.png");
const vue = require("./assets/vue.png");
const webpack = require("./assets/webpack.png");
export default {
name: "app",
data() {
return {
images: [
bulma,
bootstrap,
css3,
html5,
illustrator,
js,
photoshop,
vue,
webpack
],
idx: Math.floor(Math.random() * this.images.length),
randomImage: this.images[this.idx]
};
}
};
and HTML:
<div id="app">
<div id="myContainer">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view />
<button v-on:click="animate">Test</button>
<img v-for="image in images" :src="image" />
</div>
</div>
Error in data(): "TypeError: Cannot read property 'length' of undefined" (Vue.js)!!! problem is connected with Math.floor(Math.random() * this.images.length) as i understand. In future i want to use randomPicture to generate random pictures.
Share Improve this question edited Mar 12, 2019 at 13:16 German Varanytsya asked Mar 12, 2019 at 13:13 German VaranytsyaGerman Varanytsya 3971 gold badge4 silver badges20 bronze badges 2- Possible duplicate of Self-references in object literals / initializers – str Commented Mar 12, 2019 at 13:16
-
this.images
is undefined at the moment you're trying to use it. The data function hasn't finished yet. You can store the images in a variable and then reference that in your return statement. – Etheryte Commented Mar 12, 2019 at 13:16
4 Answers
Reset to default 3When you create your ponent with this :
export default {
name: "app",
data() {
return {
images: [
bulma,
bootstrap,
css3,
html5,
illustrator,
js,
photoshop,
vue,
webpack
],
idx: Math.floor(Math.random() * this.images.length),
randomImage: this.images[this.idx]
};
}
};
this.images
(or this.idx
) is not yet defined. You should set a value (like null
) to randomImage
, then set the actual value on the created
hook :
export default {
name: "app",
data() {
return {
images: [
bulma,
bootstrap,
css3,
html5,
illustrator,
js,
photoshop,
vue,
webpack
],
idx: null,
randomImage: null
};
},
created() {
this.idx = Math.floor(Math.random() * this.images.length)
this.randomImage = this.images[this.idx]
}
};
You can use a puted property instead to data variables like this:
export default {
name: "app",
data() {
return {
images: [
bulma,
bootstrap,
css3,
html5,
illustrator,
js,
photoshop,
vue,
webpack
],
};
},
puted: {
idx() {
return Math.floor(Math.random() * this.images.length);
},
randomImage() {
return this.images[this.idx];
},
},
};
Also you can only use the ponent data variables once the ponent is created or mounted.
Your data is empty when ponent is mounted (because you get it asynchronously), so you need an additional guard.
Like other answers indicate, this.images is not yet defined when you use it. So try this:
const bootstrap = require("./assets/bootstrap.png");
const bulma = require("./assets/bulma.png");
const css3 = require("./assets/css3.png");
const html5 = require("./assets/html5.png");
const illustrator = require("./assets/illustrator.png");
const js = require("./assets/js.png");
const photoshop = require("./assets/photoshop.png");
const vue = require("./assets/vue.png");
const webpack = require("./assets/webpack.png");
export default {
name: "app",
data() {
const images = [
bulma,
bootstrap,
css3,
html5,
illustrator,
js,
photoshop,
vue,
webpack
]
const idx = Math.floor(Math.random() * images.length)
return {
images,
idx,
randomImage: images[idx]
};
}
};