Home > Software engineering >  How to do a function call in HTML with vueJS
How to do a function call in HTML with vueJS

Time:02-10

For my dev lessons, I need to create a social network for a company.

One of the functionalities is to display the comment number linked to a publication (a bit like on Facebook).

To get the comments, I am using vueX to get all data from one source. So, to display the comment count number, here is my idea : for each publication contained in an array, I get all publication comments in another array. So, if I do a {{comments.length}}, for example, this should display "3 comments"

So I wrote the following code :

  <div v-if="publications.length > 0">
    <AddPostForm />
    <section
      v-for="post in publications"
      :key="post.postId"
      
    >
      <div v-bind:data-id="post.postId" >
        <div  :data-user-id="post.userId">
          <img :src="post.avatarUrl" alt="Photo de profil" />&nbsp;
          <span
            
            @click="goToProfile(post.userId)"
          >
            {{ post.firstName }} {{ post.lastName }}
          </span>
        </div>

        <div
          
          v-if="post.postContent !== null && post.postContent !== ''"
        >
          <p>{{ post.postContent }}</p>
        </div>

        <div
          
          v-else-if="
            post.postContent === null ||
            (post.postContent === '' &&
              (post.imageUrl !== null || post.imageUrl !== ''))
          "
        >
          <img :src="post.imageUrl" alt="Image de publication" />
        </div>

        <div
          
          v-else-if="
            (post.postContent !== null || post.postContent !== '') &&
            (post.imageUrl !== null || post.imageUrl !== '')
          "
        >
          <p>{{ post.postContent }}</p>
          <img :src="post.imageUrl" alt="Image de publication" />
        </div>

        <div >
          <p>Publié le {{ post.post_date }}</p>
        </div>

        <div  v-if="user.admin === 1">
          <p  @click="deletePost(post.postId)">
            Supprimer
          </p>
        </div>
        <div
          
          v-if="post.comment_count > 0"
        >
          <div
            
            @click="goToComments(post.userId, post.postId)"
            v-if="comments.length === 1"
          >
            {{ comments.length }} commentaire
          </div>

          <div
            
            @click="goToComments(post.userId, post.postId)"
            v-else
          >
            {{ comments.length }} commentaires
          </div>
        </div>

        <div >
          <div >
            <FaSolidHeart />
            <span >&nbsp;J'aime</span>
          </div>

          <div  @click="comment = true">
            <FaSolidComment />
            <span
              
              @click="goToComments(post.userId, post.postId)"
              >&nbsp;Commenter</span
            >
          </div>
        </div>
      </div>
    </section>
  </div>
  <div v-else-if="publications.length === 0">
    <p>Aucune publication pour le moment</p>
  </div>
</template>

<script>
import axios from 'axios';
import { mapState } from 'vuex';

import FaSolidHeart from './Heart.vue';
import FaSolidComment from './CommentIcon.vue';
import AddPostForm from './AddPost.vue';

const userSessionData = JSON.parse(localStorage.getItem('userSession'));
const sessionToken = userSessionData.token;
if (sessionToken) {
  axios.defaults.headers.common['Authorization'] = 'Bearer '   sessionToken;
}

export default {
  name: 'Wall',
  components: {
    FaSolidHeart,
    FaSolidComment,
    AddPostForm
  },
  data() {
    return {
      comment: false,
      user: []
    };
  },
  beforeMount() {
    this.getResult();
    this.getSession();
  },
  methods: {
    getResult: function () {
      this.$store.dispatch('setPublications');
    },
    goToProfile: function (userId) {
      this.$router.push(`/profile/${userId}`);
    },
    goToComments: function (userId, postId) {
      this.$router.push(`/comments/${userId}/${postId}`);
    },
    getSession: function () {
      if (localStorage.userSession) {
        this.user = JSON.parse(localStorage.userSession);
      }
    },
    deletePost: function (postId) {
      axios
        .delete(`http://localhost:3000/api/publications/${postId}`)
        .then(() => this.$router.go())
        .catch((error) => console.log(error));
    },
    getComments: function (postId) {
      // this.$store.dispatch('getPublicationComments', postId);
      console.log(postId);
    }
  },
  computed: {
    ...mapState(['publications', 'comments'])
  }
};
</script>

<style scoped>
.publications {
  width: 30%;
  margin: 10px auto;
}

.publications__card {
  width: 99%;
  padding: 10px;
  padding-left: 15px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background-color: rgba(138, 185, 241, 0.4);
}

.publications__card .publications__author:hover {
  cursor: pointer;
}

.publications__card .publications__date-time {
  margin-top: -20px;
  font-size: 0.8rem;
  color: grey;
}

.publications__card .publications__delete .publications__delete-txt {
  margin-top: -5px;
  font-size: 0.85rem;
}

.publications__card .publications__like-comment-count {
  width: 92%;
  height: fit-content;
  margin: auto 0;
  padding: 5px;
  border-top: 1px solid white;
}

.publications__card .publications__comment-count {
  margin-right: 15px;
  text-align: right;
}

.publications__card .publications__like-comment {
  width: 95%;
  height: fit-content;
  margin: auto 0;
  padding-top: 10px;
  display: flex;
  justify-content: space-around;
  border-top: 1px solid white;
}

.publications__card .like-comment__like:hover,
.publications__card .like-comment__comment:hover,
.publications__card .publications__comment-count:hover,
.publications__card .publications__delete .publications__delete-txt:hover {
  cursor: pointer;
  color: #4b77be;
}

.publications__card .publications__add-comment {
  width: 95%;
  padding-top: 5px;
  border-top: 1px solid white;
}

.publications__card .publications__add-comment .add-comment__field {
  width: 98%;
  height: 25px;
  margin-top: 5px;
  padding-top: 0px;
  padding: 13px;
  border-radius: 50px;
  resize: none;
  font-family: 'poppins';
  outline: none;
}
</style>

My question is how may I call the getComments function from the HTML so that I can display comment count number properly ?

Thank you so much for your help :)

CodePudding user response:

You can simply do {{ getComments() }} in your markup.

CodePudding user response:

Thanks to your advice, I wrote the following code, but this is still not working :

  <div v-if="publications.length > 0">
    <AddPostForm />
    <section
      v-for="post in publications"
      :key="post.postId"
      
    >
      {{ getCommentCount(post.postId) }}
      {{ comments }}
      <div v-bind:data-id="post.postId" >
        <div  :data-user-id="post.userId">
          <img :src="post.avatarUrl" alt="Photo de profil" />&nbsp;
          <span
            
            @click="goToProfile(post.userId)"
          >
            {{ post.firstName }} {{ post.lastName }}
          </span>
        </div>

        <div
          
          v-if="post.postContent !== null && post.postContent !== ''"
        >
          <p>{{ post.postContent }}</p>
        </div>

        <div
          
          v-else-if="
            post.postContent === null ||
            (post.postContent === '' &&
              (post.imageUrl !== null || post.imageUrl !== ''))
          "
        >
          <img :src="post.imageUrl" alt="Image de publication" />
        </div>

        <div
          
          v-else-if="
            (post.postContent !== null || post.postContent !== '') &&
            (post.imageUrl !== null || post.imageUrl !== '')
          "
        >
          <p>{{ post.postContent }}</p>
          <img :src="post.imageUrl" alt="Image de publication" />
        </div>

        <div >
          <p>Publié le {{ post.post_date }}</p>
        </div>

        <div  v-if="user.admin === 1">
          <p  @click="deletePost(post.postId)">
            Supprimer
          </p>
        </div>
        <div
          
          v-if="post.comment_count > 0"
        >
          <div
            
            @click="goToComments(post.userId, post.postId)"
            v-if="comments.length === 1"
          >
            {{ comments.length }} commentaire
          </div>

          <div
            
            @click="goToComments(post.userId, post.postId)"
            v-else
          >
            {{ comments.length }} commentaires
          </div>
        </div>

        <div >
          <div >
            <FaSolidHeart />
            <span >&nbsp;J'aime</span>
          </div>

          <div  @click="comment = true">
            <FaSolidComment />
            <span
              
              @click="goToComments(post.userId, post.postId)"
              >&nbsp;Commenter</span
            >
          </div>
        </div>
      </div>
    </section>
  </div>
  <div v-else-if="publications.length === 0">
    <p>Aucune publication pour le moment</p>
  </div>
</template>

<script>
import axios from 'axios';
import { mapState } from 'vuex';

import FaSolidHeart from './Heart.vue';
import FaSolidComment from './CommentIcon.vue';
import AddPostForm from './AddPost.vue';

const userSessionData = JSON.parse(localStorage.getItem('userSession'));
const sessionToken = userSessionData.token;
if (sessionToken) {
  axios.defaults.headers.common['Authorization'] = 'Bearer '   sessionToken;
}

export default {
  name: 'Wall',
  components: {
    FaSolidHeart,
    FaSolidComment,
    AddPostForm
  },
  data() {
    return {
      comment: false,
      user: [],
      commentCount: 0
    };
  },
  beforeMount() {
    this.getResult();
    this.getSession();
  },
  methods: {
    getResult: function () {
      this.$store.dispatch('setPublications');
    },
    goToProfile: function (userId) {
      this.$router.push(`/profile/${userId}`);
    },
    goToComments: function (userId, postId) {
      this.$router.push(`/comments/${userId}/${postId}`);
    },
    getSession: function () {
      if (localStorage.userSession) {
        this.user = JSON.parse(localStorage.userSession);
      }
    },
    deletePost: function (postId) {
      axios
        .delete(`http://localhost:3000/api/publications/${postId}`)
        .then(() => this.$router.go())
        .catch((error) => console.log(error));
    },
    getComments: function (postId) {
      this.$store.dispatch('getPublicationComments', postId);
    }
  },
  computed: {
    ...mapState(['publications', 'comments']),
    getCommentCount: function (postId) {
      this.$store.dispatch('getPublicationComments', postId);
      return this.$store.state.comments;
    }
  }
};
</script>

<style scoped>
.publications {
  width: 30%;
  margin: 10px auto;
}

.publications__card {
  width: 99%;
  padding: 10px;
  padding-left: 15px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background-color: rgba(138, 185, 241, 0.4);
}

.publications__card .publications__author:hover {
  cursor: pointer;
}

.publications__card .publications__date-time {
  margin-top: -20px;
  font-size: 0.8rem;
  color: grey;
}

.publications__card .publications__delete .publications__delete-txt {
  margin-top: -5px;
  font-size: 0.85rem;
}

.publications__card .publications__like-comment-count {
  width: 92%;
  height: fit-content;
  margin: auto 0;
  padding: 5px;
  border-top: 1px solid white;
}

.publications__card .publications__comment-count {
  margin-right: 15px;
  text-align: right;
}

.publications__card .publications__like-comment {
  width: 95%;
  height: fit-content;
  margin: auto 0;
  padding-top: 10px;
  display: flex;
  justify-content: space-around;
  border-top: 1px solid white;
}

.publications__card .like-comment__like:hover,
.publications__card .like-comment__comment:hover,
.publications__card .publications__comment-count:hover,
.publications__card .publications__delete .publications__delete-txt:hover {
  cursor: pointer;
  color: #4b77be;
}

.publications__card .publications__add-comment {
  width: 95%;
  padding-top: 5px;
  border-top: 1px solid white;
}

.publications__card .publications__add-comment .add-comment__field {
  width: 98%;
  height: 25px;
  margin-top: 5px;
  padding-top: 0px;
  padding: 13px;
  border-radius: 50px;
  resize: none;
  font-family: 'poppins';
  outline: none;
}
</style>

CodePudding user response:

I am not sure if this will work, but if you store the comments in vuex, you can use this:

<p>{{ this.$store.state.comments.length }}<p>

This only works if the comments is correctly stored in vuex, I hope this will work for you.

  • Related