How do I fetch JSON data with Vue and Axios

13,078

As the warnings suggest, please do the following:

  1. Rename the data array from results to products since you are referencing it by the latter one as a name during render.
  2. 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.
Vue.component('products', {
  data() {
    return {
      products: []
    }
  },

  mounted() {
    axios
      .get("js/prods.json")
      .then(response => {
        this.products = response.data.products;
      });
  },

  template: `
    //...
  `
}

<div id="products">
  <div class="productsItemContainer" v-for="product in products">
    <div class="productsItem">
 ...

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

<template>
  <div id="products">
    <div class="productsItemContainer" v-for="product in products">
      <div class="productsItem">
        <!-- The rest of the elements -->

      </div>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Products',

    data() {
      return {
        products: []
      }
    },

    mounted() {
      axios
        .get("js/prods.json")
        .then(response => {
          this.products = response.data.products;
        });
    }
  }
</script>

And then in your main JS file or anywhere else requiring this component:

import Products from './components/Products.vue';

new Vue({
  el: '#app',

  data() {
    return {
      //...
    }
  },

  components: {
    Products
  }
})
<div id="app">

  <Products />

</div>
Share:
13,078
MK01111000
Author by

MK01111000

Updated on June 04, 2022

Comments

  • MK01111000
    MK01111000 almost 2 years

    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:

    Vue.component('products',{
    data: {
        results: []
    },
    mounted() {
        axios.get("js/prods.json")
        .then(response => {this.results = response.data.results})
    },
    template:`
    <div id="products">
    <div class="productsItemContainer" v-for="product in products">
                <div class="productsItem">
                    <div class="">
                        <div class="mkcenter" style="position:relative">
                            <a class="item">
                                <img class="productImg" width="120px" height="120px" v-bind:src="'assets/products/' + product.image">
                                <div class="floating ui red label" v-if="product.new">NEW</div>
                            </a>
                        </div>
                    </div>
                    <div class="productItemName" >
                        <a>{{ product.name }}</a>
                    </div>
                    <div class="mkdivider mkcenter"></div>
                    <div class="productItemPrice" >
                        <a>€ {{ product.unit_price }}</a>
                    </div>
                    <div v-on:click="addToCart" class="mkcenter">
                        <div class="ui vertical animated basic button" tabindex="0">
                            <div class="hidden content">Koop</div>
                            <div class="visible content">
                                <i class="shop icon"></i>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        `
    })
    new Vue({
    el:"#app",
    });
    

    The json file is as follows

    {
        "products":[
            {
                "name": "Danser Skydancer",
                "inventory": 5,
                "unit_price": 45.99,
                "image":"a.jpg",
                "new":true
            },
            {
                "name": "Avocado Zwem Ring",
                "inventory": 10,
                "unit_price": 123.75,
                "image":"b.jpg",
                "new":false
            }
        ]
    }
    

    The problem is only with the fetching of the data from a JSON file, because the following worked:

    Vue.component('products',{
        data:function(){
            return{
                reactive:true,
                products: [
               {
                name: "Danser Skydancer",
                inventory: 5,
                unit_price: 45.99,
                image:"a.jpg",
                new:true
              },
              {
                name: "Avocado Zwem Ring",
                inventory: 10,
                unit_price: 123.75,
                image:"b.jpg",
                new:false
              }
                ],
              cart:0
            }
        },
       template: etc.........
    
    • Yom T.
      Yom T. about 5 years
      What do you see in the console? Also, you will want to v-for the results rather than products, unless that is a typo...
    • MK01111000
      MK01111000 about 5 years
      The console shows the following: vue.js:616 [Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.
    • MK01111000
      MK01111000 about 5 years
      and<br> vue.js:616 [Vue warn]: Property or method "products" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: vuejs.org/v2/guide/…. found in ---> <Products> <Root>
    • Yom T.
      Yom T. about 5 years
      Are you running Vue with CDN?
    • MK01111000
      MK01111000 about 5 years
      No I downloaded it. Both Vue and Axios work properly. The problem isnt with the files. The following displays the correct data in the console axios.get('/js/products.json') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }) .then(function () { // always executed });
    • Yom T.
      Yom T. about 5 years
      First of all, please change your array name from results to products and make the data part a function returning the objects/data.
    • MK01111000
      MK01111000 about 5 years
      I changed t=rsult to products, but do not get your 2nd suggestion. How is this done?