I’m trying to fetch product data from a JSON file, but can’t get it to work. I’ve tried several things and searched the internet for a solution but none of the examples on the internet equals my situation. I’m new to both vue and axios, so please excuse my ignorance.
This is what I have so far:
JavaScript
x
44
44
1
Vue.component('products',{
2
data: {
3
results: []
4
},
5
mounted() {
6
axios.get("js/prods.json")
7
.then(response => {this.results = response.data.results})
8
},
9
template:`
10
<div id="products">
11
<div class="productsItemContainer" v-for="product in products">
12
<div class="productsItem">
13
<div class="">
14
<div class="mkcenter" style="position:relative">
15
<a class="item">
16
<img class="productImg" width="120px" height="120px" v-bind:src="'assets/products/' + product.image">
17
<div class="floating ui red label" v-if="product.new">NEW</div>
18
</a>
19
</div>
20
</div>
21
<div class="productItemName" >
22
<a>{{ product.name }}</a>
23
</div>
24
<div class="mkdivider mkcenter"></div>
25
<div class="productItemPrice" >
26
<a>€ {{ product.unit_price }}</a>
27
</div>
28
<div v-on:click="addToCart" class="mkcenter">
29
<div class="ui vertical animated basic button" tabindex="0">
30
<div class="hidden content">Koop</div>
31
<div class="visible content">
32
<i class="shop icon"></i>
33
</div>
34
</div>
35
</div>
36
</div>
37
</div>
38
</div>
39
`
40
})
41
new Vue({
42
el:"#app",
43
});
44
The json file is as follows
JavaScript
1
19
19
1
{
2
"products":[
3
{
4
"name": "Danser Skydancer",
5
"inventory": 5,
6
"unit_price": 45.99,
7
"image":"a.jpg",
8
"new":true
9
},
10
{
11
"name": "Avocado Zwem Ring",
12
"inventory": 10,
13
"unit_price": 123.75,
14
"image":"b.jpg",
15
"new":false
16
}
17
]
18
}
19
The problem is only with the fetching of the data from a JSON file, because the following worked:
JavaScript
1
25
25
1
Vue.component('products',{
2
data:function(){
3
return{
4
reactive:true,
5
products: [
6
{
7
name: "Danser Skydancer",
8
inventory: 5,
9
unit_price: 45.99,
10
image:"a.jpg",
11
new:true
12
},
13
{
14
name: "Avocado Zwem Ring",
15
inventory: 10,
16
unit_price: 123.75,
17
image:"b.jpg",
18
new:false
19
}
20
],
21
cart:0
22
}
23
},
24
template: etc
25
Advertisement
Answer
As the warnings suggest, please do the following:
- Rename the data array from
results
toproducts
since you are referencing it by the latter one as a name during render. - Make your data option a function returning an object since data option must be a function, so that each instance can maintain an independent copy of the returned data object. Have a look at the docs on this.
JavaScript
1
21
21
1
Vue.component('products', {
2
data() {
3
return {
4
products: []
5
}
6
},
7
8
mounted() {
9
axios
10
.get("js/prods.json")
11
.then(response => {
12
this.products = response.data.products;
13
});
14
},
15
16
template: `
17
//...
18
`
19
}
20
21
JavaScript
1
5
1
<div id="products">
2
<div class="productsItemContainer" v-for="product in products">
3
<div class="productsItem">
4
5
Also, since you’re not using CDN (I think), I would suggest making the template a component with a separate Vue file rather than doing it inside template literals, something like that:
Products.vue
JavaScript
1
31
31
1
<template>
2
<div id="products">
3
<div class="productsItemContainer" v-for="product in products">
4
<div class="productsItem">
5
<!-- The rest of the elements -->
6
7
</div>
8
</div>
9
</div>
10
</template>
11
12
<script>
13
export default {
14
name: 'Products',
15
16
data() {
17
return {
18
products: []
19
}
20
},
21
22
mounted() {
23
axios
24
.get("js/prods.json")
25
.then(response => {
26
this.products = response.data.products;
27
});
28
}
29
}
30
</script>
31
And then in your main JS file or anywhere else requiring this component:
JavaScript
1
16
16
1
import Products from './components/Products.vue';
2
3
new Vue({
4
el: '#app',
5
6
data() {
7
return {
8
//...
9
}
10
},
11
12
components: {
13
Products
14
}
15
})
16
JavaScript
1
6
1
<div id="app">
2
3
<Products />
4
5
</div>
6