Luke Grech
Luke Grech

Reputation: 185

Display Vue Computed Array of Objects in HTML

I am having trouble displaying an array of objects from Vue that is fetched from an express server using fetch(); The fetching of the data works but I am not sure as how to display it in html. Below is the Vue code that is successfully fetching the JSON from Express.

computed: {     
        async fetchData() {
            fetch('http://localhost:4000/lessons').then(
            function (response) {
            response.json().then(
                function (json) {
                    this.lessons = json;
                    console.log(this.lessons)
                });
            })
        },     
    }

The console.log successfully displays the fetched array of objects but it is not being displayed in HTML. Below is the HTML code that is not displaying the fetched array of objects.

<div v-for="lesson in fetchData" class="card">
                    <h2 v-text ="lesson.subject"></h2>
                    <figure>
                        <img v-bind:src="lesson.image">
                    </figure>
                    <p>Location: {{lesson.location}}</p>
                    <p>Price: £{{lesson.price}}</p>
                    <p>Description: {{lesson.description}}</p>
                    <p>Maximum Class Size: {{lesson.maximumSpaces}} People</p>             
                </div>

How will I be able to display the array of objects in the HTML file? Thanks for your time.

Upvotes: 3

Views: 627

Answers (1)

Dan
Dan

Reputation: 63119

There are a few problems: 1) Computeds are not async. 2) The template is not async, so you could not call even an async method that way. 3) Your fetch callback function should be an arrow function or it injects its own this and blocks the data setting. 4) Use a :key with v-for. Here is a proper pattern, use a method to fetch the data:

methods: {
   async fetchData() {
      const response = await fetch('http://localhost:4000/lessons');
      this.lessons = await response.json();
   }
}

You can call it in the created or mounted lifecycle hook, or somewhere else:

data: () => ({
   lessons: []
}),
created() {
   this.fetchData()
}

Then iterate over the data:

<div v-for="(lesson, index) in lessons" class="card" :key="index">
...
</div>

Here is a demo:

new Vue({
  el: "#app",
  data: () => ({
    lessons: []
  }),
  created() {
    this.fetchData()
  },
  methods: {
    async fetchData() {
      const response = await fetch('https://jsonplaceholder.typicode.com/todos');
      this.lessons = await response.json();
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="(lesson, index) in lessons" :key="index">
  {{ lesson }}
  </div>
</div>

Upvotes: 4

Related Questions