carlhandy
carlhandy

Reputation: 315

DIsplay data from JSON API using vuejs and axios

Below is my JS and HTML code for a Vue.js application I'm building.

The data returns fine but I'm unable to display it on the front.

Any help would be appreciated.

data() {
    return {
      overview: this.getOverview()
    }

  },
  methods: {
    getOverview() {
      return axios.get('http://localhost:8000/v1/overview')
        .then(response => {
          this.results = response.data
          console.log('results data', this.results)
        })
        .catch(function(error) {
          console.log(error);
        })
    }
  }
<tr v-for="overview in overview">
  <td>
    {{overview.id}}
  </td>

  <td></td>
  <td class="text-right">
    {{overview.schools}}
  </td>
  <td class="text-right">
    {{overview.primary}}
  </td>
  <td class="text-right">
    {{overview.secondary}}
  </td>

</tr>
JSON data

{"schools":545,"counsellors":4,"reports":13,"sub_regions":[{"id":1,"name":"Barima-Waini","schools":45,"primary":42,"secondary":3},{"id":2,"name":"Pomeroon-Supenaam","schools":45,"primary":37,"secondary":8},{"id":3,"name":"Essequibo Islands-West Demerara","schools":72,"primary":59,"secondary":13},{"id":4,"name":"Georgetown","schools":69,"primary":54,"secondary":15},{"id":5,"name":"Outside Georgetown","schools":62,"primary":31,"secondary":31},{"id":6,"name":"Mahaica-Berbice","schools":39,"primary":32,"secondary":7},{"id":7,"name":"East Berbice-Corentyne","schools":71,"primary":54,"secondary":17},{"id":8,"name":"Cuyuni-Mazaruni","schools":31,"primary":28,"secondary":3},{"id":9,"name":"Potaro-Siparuni","schools":22,"primary":20,"secondary":2},{"id":10,"name":"Upper Takutu-Upper Essequibo","schools":49,"primary":45,"secondary":4},{"id":11,"name":"Upper Demerara-Upper Berbice","schools":40,"primary":32,"secondary":8}]}

Upvotes: 0

Views: 2675

Answers (1)

Aluan Haddad
Aluan Haddad

Reputation: 31873

Disclaimer: I've never really used Vue myself

The problem is that you are databinding in your view to a view model property named overview. The value of overview is a Promise that will inevitably resolve with undefined, if it resolves, because the final .then in your promise chain does not return a value:

return axios.get('http://localhost:8000/v1/overview')
  .then(response => {
     this.results = response.data;
     console.log('results data', this.results);
   })
   .catch(function(error) {
     console.log(error);
   });

As you can see, we are assigning the response from the API call to a result property but that is not what we are binding to. I believe that, as Bert suggests, you need assign to this.overview instead of this.result if possibly, I would prefer to simply return the resolved value in the promise chain.

Speaking of promise chains, since you are using Vue, you are transpiling, since you are transpiling, you should leverage async/await for superior readability.

Consider writing code such as

async getOverview() {
  try {
    const {data:{json:{sub_regions}}} = await axios.get('http://localhost:8000/v1/overview');
    console.log('results data', sub_regions);
    this.overview = sub_regions;
  }
  catch (error) {
    console.log(error);
    return [];
  }
}

Thank to Bert's link and helpful analysis, I have updated the answer to reflect a common Vue pattern

You will end up with something like this

new Vue({
  el: "#app",
  data() {
    return {
      overview: []
    }

  },
  methods: {
    async getOverview() {
      try {
        const {data:{json:{sub_regions}}} = await axios.get('http://localhost:8000/v1/overview');
        console.log('results data', sub_regions);
        this.overview = sub_regions;
      }
      catch (error) {
        console.log(error);
        return [];
      }
    }
  },
  created(){
    this.getOverview()
  }
})

Upvotes: 2

Related Questions