Home > Software engineering >  Sending props for components using v-for in Vue JS
Sending props for components using v-for in Vue JS

Time:11-28

I implemented the changes proposed in the comments. It is now working! Thanks a lot to everybody for your help

------------ Inital help request below : -------------------

I have a Home.vue parent component that I use as a home page. On this page I make a fetch request to have an array of posts. I try with a v-for to iterate through the array of posts and send each time a new post object.

My problem is the following:

  • the array is send in full and thus only one Post template is generated...

Thank you in advanced for your time and I did some research, but without any success.

Find below the Home.vue parent component

<template>
  <div >
      <div v-for="(post, index) in posts" :key="index">
         <ImageArticle 
         :articledata="post"
         />
  </div>
  </div>
</template>

<script>
import ImageArticle from "../components/imageArticle"
import { mapState } from "vuex"

export default {
  name: 'Home',
  components: {
    ImageArticle,
  },
  data() {
    return {
      posts : [],
    }
  },
    computed: {
        ...mapState({
            UserName: "UserName",
            UserLogin: "UserLogin",
            UserEmail: "UserEmail",
            UserPublications: "UserPublications",
            UserFriends: "UserFriends"
    })
  },
  created() {
    this.getAllPosts()
  },
  methods:{
    getAllPosts () {

      var requestOptions = {
      method: 'GET',
      redirect: 'follow'
      };

      fetch("http://localhost:3000/api/post/", requestOptions)
      .then(response => response.text())
      .then((result) => {
        this.posts = JSON.parse(result);
        console.log(this.posts);
      })
      .catch(error => console.log('error', error));
    }
  }
}
</script>

Find below the child component, to which I try to send the post object, as a prop. (I deleted a lot of the code, to make it more readable)

<template>
    <div>
        <article >
                    <h4 >Kaerbran {{articleData.Post_Comment}}</h4>
        </article>
    </div>
</template>


<script>
import ModalBoxActionArticle from '../components/modalBoxActionArticle'

export default {
    name: 'ImageArticle',
    props : ['articledata'],
    data() {
        return {
            articleData : this.articledata,
        }
    }
}
</script>

Find below the array I'm sending. I want to create a new template for each Post_ID.

"posts": [
        {
            "Post_ID": "48be1774-4563-478b-9201-56ab2887d9a1",
            "Post_Picture": "placeholder.png",
            "Post_Location": "ParisII",
            "Post_Date_published": "2021-10-22T17:43:10.281Z",
            "Post_Date_modified": "2021-10-22T17:43:10.281Z",
            "Post_Comment": "un commentaire",
            "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"
        },
        {
            "Post_ID": "88ce1c98-ad16-4987-82c9-f8a9abff7f33",
            "Post_Picture": "placeholder.png",
            "Post_Location": "ParisII",
            "Post_Date_published": "2021-10-22T17:44:12.985Z",
            "Post_Date_modified": "2021-10-22T17:44:12.985Z",
            "Post_Comment": "un commentaire",
            "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"
        },
        {
            "Post_ID": "b43abd59-ce16-4c0e-a3e6-03402a35ecfc",
            "Post_Picture": "placeholder.png",
            "Post_Location": "ParisIII",
            "Post_Date_published": "2021-10-22T17:45:23.013Z",
            "Post_Date_modified": "2021-10-22T17:45:23.013Z",
            "Post_Comment": "un commentaire",
            "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"
        },
        {
            "Post_ID": "f2737804-9493-42d9-b425-51334c3a360a",
            "Post_Picture": "placeholder.png",
            "Post_Location": "Paris",
            "Post_Date_published": "2021-10-22T17:15:56.994Z",
            "Post_Date_modified": "2021-10-22T17:15:56.994Z",
            "Post_Comment": "un commentaire",
            "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"
        },
        {
            "Post_ID": "fcd4d5a0-c771-4243-99d9-b374b00c2159",
            "Post_Picture": "placeholder.png",
            "Post_Location": "ParisIII",
            "Post_Date_published": "2021-10-22T17:45:01.362Z",
            "Post_Date_modified": "2021-10-22T17:45:01.362Z",
            "Post_Comment": "un commentaire",
            "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"
        }
    ]
}

CodePudding user response:

Few things to note:

First, the way you pass a key for the iterated elements is wrong. Passing and index of the array results in unpredictable results or ui not getting updated. Change this line from

v-bind:key="{index}"

to

  v-bind:key="post.Post_ID"

Then, also how you are passing the data to the props is wrong, change from

v-bind:sendArticleData = post

to

v-bind:send-article-data="post"

or even simplier to:

:send-article-data="post"

Read more about props casing in Vue here

CodePudding user response:

If I understood you correctly try like following snippet:

Vue.component('Child', {
  template: `
    <div >
      <div >
        <h4 >Kaerbran {{articleData.Post_Comment}}</h4>
      </div>
    </div>
  `,
  props : ['articledata'],
  data() {
    return {
      articleData : this.articledata,
    }
  }
})


new Vue({
  el: '#demo',
  data() {
    return {
      posts: [
        {"Post_ID": "48be1774-4563-478b-9201-56ab2887d9a1", "Post_Picture": "placeholder.png", "Post_Location": "ParisII", "Post_Date_published": "2021-10-22T17:43:10.281Z", "Post_Date_modified": "2021-10-22T17:43:10.281Z",                "Post_Comment": "un commentaire1", "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"},
       {"Post_ID": "88ce1c98-ad16-4987-82c9-f8a9abff7f33", "Post_Picture": "placeholder.png", "Post_Location": "ParisII", "Post_Date_published": "2021-10-22T17:44:12.985Z", "Post_Date_modified": "2021-10-22T17:44:12.985Z",             "Post_Comment": "un commentaire2", "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"},
       {"Post_ID": "b43abd59-ce16-4c0e-a3e6-03402a35ecfc", "Post_Picture": "placeholder.png", "Post_Location": "ParisIII", "Post_Date_published": "2021-10-22T17:45:23.013Z", "Post_Date_modified": "2021-10-22T17:45:23.013Z",               "Post_Comment": "un commentaire3", "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"},
       {"Post_ID": "f2737804-9493-42d9-b425-51334c3a360a", "Post_Picture": "placeholder.png", "Post_Location": "Paris", "Post_Date_published": "2021-10-22T17:15:56.994Z", "Post_Date_modified": "2021-10-22T17:15:56.994Z",              "Post_Comment": "un commentaire4", "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"},
       {"Post_ID": "fcd4d5a0-c771-4243-99d9-b374b00c2159", "Post_Picture": "placeholder.png", "Post_Location": "ParisIII", "Post_Date_published": "2021-10-22T17:45:01.362Z", "Post_Date_modified": "2021-10-22T17:45:01.362Z",              "Post_Comment": "un commentaire5", "Post_Creator": "d4d2c7d4-e710-4842-9622-915ed21bdd71"}
        ]
      }
  },
})

Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div class="home">
    <div  v-for="(post, index) in posts" :key="index">
      <Child 
        :articledata="post"
        class="home__component"/>
     </div>
  </div>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related