4

I am trying to create an example about the list of photos and I see a trouble when binding data to the component after call API.

JS code:

<script>
// photo item
Vue.component('photo-item', {
   props: ['photo'],
   template: `<li>{{ photo.name }}</li>`
});

// List of photos
Vue.component('photo-list', {
   props: ['photos'],

   template: `
   <ul id="photo-list">
      <photo-item v-for="photo in photos" :photo="photo"></photo-item>
   </ul>`
});

new Vue({
   el: "#photo_detail",
   data: {
      photos: []
   },

   created: function() {
      axios
       .get('/api/photos')
       .then(function (response) {
           this.photos = response.data; // Data existed
       })
       .catch(function (err) {
           console.log(err);
       });
   }
 })
 </script>

HTML code

<main id="photo_detail">
    <photo-list v-for="photo in photos" :photo="photo"></photo-list>
</main>

After fetching all photos from API and as my understand then the variable photos will auto binding and VueJS will update DOM.

VueJs 2.1.6

Any help.

Thanks!

0

2 Answers 2

14

Issue is with your this value inside function() which has this value scoped to axios instead of vue instance . or you can use (response)=> to use this directly

new Vue({
   el: "#photo_detail",
   data: {
      photos: []
   },

   created: function() {
      var self=this;
      axios
       .get('/api/photos')
       .then(function (response) {
           self.photos = response.data; // Data existed
       })
       .catch(function (err) {
           console.log(err);
       });
   }
 })
Sign up to request clarification or add additional context in comments.

2 Comments

Ahhhhhh...yeah, that great, so basic :D, thank you @Helping hand, close my issue :D
It works but gives this error: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
0

Your code is not correct.

Problems:

  1. It will be better to define used components for each component, like components: {photoItem}.
  2. In your axios callback you use function and that means, that you use wrong context inside (this.photos). Use arrow function (() => {}) instead of the function () {}
  3. The directive v-for requires directive :key=""

I've fixed it below.

// photo item
const photoItem = Vue.component('photo-item', {
   props: ['photo'],
   template: `<li>{{ photo.name }}</li>`
});

// List of photos
const photoList = Vue.component('photo-list', {

  // define used components
  components: {photoItem},
  props: ['photos'],
  template: `
   <ul id="photo-list">

      <!-- add :key="" directive -->
      <photo-item v-for="(photo, index) in photos" :key="index" :photo="photo"></photo-item>
   </ul>`
});


new Vue({
   el: "#photo_detail",

   // define used components
   components: {photoList},
   data: {
      photos: []
   },

   created: function() {

      // axios.get('/api/photos')
      // use arrow function
      setTimeout(() => {
		this.photos = [{name: 'Photo 1'}, {name: 'Photo 2'}];
      }, 1000);
   }
 })
<script src="https://unpkg.com/vue"></script>

<main id="photo_detail">
  <photo-list :photos="photos"></photo-list>
</main>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.