Home > database >  VueJS Axios Like/Dislike onClick
VueJS Axios Like/Dislike onClick

Time:08-03

I am trying to build a like button on vuejs using axios.

I have a mongoDB controller that works perfectly on postman. But i can't make it work in the frontend.

I want to add the userId in the usersLiked array and i want to add 1 in the like counter on click. And if the user click on an already liked button, i want to take off his userID from the array and do 0 on the like counter.

thats my schema

const postSchema = mongoose.Schema({
    userId: { type: String, required: true, ref: "User" },
    content: { type: String, required: true, trim: true },
    imageUrl: { type: String, trim: true },
    likes: { type: Number, default: 0 },
    usersLiked: [{ type: String, ref: "User" }],
    firstname: {type: String, required: true, trim: true },
    lastname: {type: String, required: true, trim: true },
    created_at: { type: Date},
    updated_at: { type: Date }

});

this is the axios function i tried

likePost() {
            const thisPostId = localStorage.getItem("ThisPostId")
            axios
                .post('http://127.0.0.1:3000/api/post/like/'   thisPostId, {
                    headers: {
                        Authorization: "Bearer "   localStorage.getItem("token"),
                    },
                })
                .then((response) => {
                    console.log(response.data);
                    this.$set(this.post, 'usersLiked', this.post.usersLiked !== response?.data?._id)
                })
                .catch((error) => console.log(error));
        }
    },

the html

<div v-if="post.usersLiked == user._id">
                        <div >
                            <p >{{ post.likes }} like !</p>
                            <button v-on:click="likePost(post._id)" style="color: pink" type="submit"
                                title="Aimer ce post !" >
                                <font-awesome-icon icon="fa-solid fa-thumbs-up" /> Like !
                            </button>
                        </div>
                    </div>
                    <div v-else>
                        <div >
                            <p >{{ post.likes }} like !</p>
                            <button v-on:click="likePost(post._id)" type="submit" title="Aimer ce post !"
                                >
                                <font-awesome-icon icon="fa-solid fa-thumbs-up" /> Like !
                            </button>
                        </div>
                    </div>

and this is my data

data() {
        return {
            posts: [],
            post: {
                file: "",
                content: "",
            },
            showModal: false,
            showModifyPost: false,
            user: {
                firstname: "",
                lastname: "",
                _id: "",
            },
        };
    },

CodePudding user response:

Adding a computed function to get the current user's like status can be helpful here.

{
  computed: {
    myLikeStatus() {
      if (!this.user) return false
      if (!Array.isArray(this.posts.usersLiked)) return false
      return !!this.posts.usersLiked.find(item => item === this.user._id)
    }
  }
}

With this computed function you should be able to set classes on the like button to show already-liked status.

<button @click="likePost" type="submit" title="Aimer ce post !"
    
    :
>
    <font-awesome-icon :icon="`fa-solid fa-thumbs-${myLikeStatus ? 'up' : 'down'}`" /> Like !
</button>

And now in the LikePost method, just assign the response data to the reactive posts variable as:

{
  methods: {
    likePost() {
            const thisPostId = localStorage.getItem("ThisPostId")
            axios
                .post('http://127.0.0.1:3000/api/post/like/'   thisPostId, {
                    headers: {
                        Authorization: "Bearer "   localStorage.getItem("token"),
                    },
                })
                .then((response) => {
                    console.log(response.data);
                    this.post = response.data
                })
                .catch((error) => console.log(error));
        }
    },
  }
}

Also, your like count should be reactive the way it is now if the API is returning the correct count.

  • Related