For these features, we'll create a TweetReactions component then add our implementations to it. Create a TweetReactions.vue file inside src/components/Tweet and paste the code below in it:

// src/components/Tweet/TweetReactions.vue

<template>
    <div class="meta">
        <a class="reply">
            <i class="reply icon"></i>
            {{ replies.length }}
        </a>
        <a class="like" v-if="isFavoritedByUser" @click="unFavoriteTweet">
            <i class="like red icon"></i> {{ favorites.length }}
        </a>
        <a class="like" v-else @click="favoriteTweet">
            <i class="like icon"></i> {{ favorites.length }}
        </a>
    </div>
</template>

We display the number of replies and favorites a tweet has. If the authenticated user has already favorited a tweet, we give the user an option to unfavorite the tweet, otherwise we give him/her an option to favorite the tweet.

Next, let's add the JavaScript section of the component:

Table of Contents

    // src/components/Tweet/TweetReactions.vue
    
    <script>
        export default {
            name: 'TweetReactions',
            props: {
                tweet: {
                    type: Object,
                    required: true
                },
                authUser: {
                    type: Object,
                    required: true
                },
                replies: {
                    type: Array,
                    required: true
                },
                favorites: {
                    type: Array,
                    required: true
                }
            },
    
            computed: {
                isFavoritedByUser () {
                    for (const favorite of this.favorites) {
                        if (favorite.user_id === this.authUser.id) {
                            return true
                        }
                    }
    
                    return false
                }
            },
            methods: {
                favoriteTweet () {
                    const token = localStorage.getItem('tweetr-token')
    
                    if (!token) {
                        alert('You must be logged in to perform the action.')
                        return
                    }
    
                    axios
                        .post(
                            '/favorites/create',
                            { tweet_id: this.tweet.id },
                            {
                                headers: {
                                    Authorization: `Bearer ${token}`
                                }
                            }
                        )
                        .then(response => {
                            this.favorites.push(response.data.data)
                        })
                },
                unFavoriteTweet () {
                    const token = localStorage.getItem('tweetr-token')
    
                    if (!token) {
                        alert('You must be logged in to perform the action.')
                        return
                    }
    
                    axios
                        .delete(`/favorites/destroy/${this.tweet.id}`, {
                            headers: {
                                Authorization: `Bearer ${token}`
                            }
                        })
                        .then(response => {
                            const filteredFavorites = this.favorites.filter(favorite => {
                                return favorite.user_id !== this.authUser.id
                            })
    
                            this.$emit('update:favorites', filteredFavorites)
                        })
                }
            }
        }
    </script>

    This component accepts four props: the tweet, the authenticated user, the tweet's replies, and the tweet favorites. Then we define a isFavoritedByUser computed property which we use to determine if the authenticated user has already favorited the a tweet.

    To favorite a tweet, we make a POST request to /favorites/create endpoint of our API pasing along the ID of the tweet the user want to favorite and also the user's token. On success, we add the new favorite data to the favorites array. We add a little check to make sure only authenticated users can favorite tweets.

    To unfavorite a tweet, we make a DELETE request to /favorites/destroy/:id endpoint of our API passing along the user's token. Where :id is the ID of the tweet the user want to unfavorite. On success, we filter the favorites array by removing the authenticated user from the list of users that have favorited the tweet. Finally, we fire a update:favorites event passing to it the filtered favorites array. By doing this, we are making sure the TweetReactions component is updated accordingly whereever it is been used.

    Now, we can start using the TweetReactions component. We'll start by adding it to the SingleTweet component, we'll add it immediately after the div that holds the tweet:

    // src/components/Tweet/SingleTweet.vue
    
    <TweetReactions
        :tweet="tweet"
        :replies="replies"
        :favorites.sync="tweet.favorites"
        :auth-user="authUser"
    />

    Doing :favorites.sync will allow the component to listen for the event fired above.

    Next, let's update the JavaScript section of the SingleTweet component accordingly:

    // src/components/Tweet/SingleTweet.vue
    
    import TweetReactions from '@/components/Tweet/TweetReactions'
    
    // add this to `components`
    TweetReactions
    
    // add this to `data`
    authUser: ''
    
    // add this to `created()`
    this.fetchAuthenticatedUser()
    
    // add this to `methods`
    fetchAuthenticatedUser () {
        const token = localStorage.getItem('tweetr-token')
    
        axios
            .get('account/me', {
                headers: {
                    Authorization: `Bearer ${token}`
                }
            })
            .then(response => {
                this.authUser = response.data.data
            })
    }

    We fetch the authenticated user.

    In the same vein, let's add the TweetReactions component to the Tweet component. We'll add it immediately after </router-link>:

    // src/components/Tweet/Tweet.vue
    
    <TweetReactions
        :tweet="tweet"
        :replies="tweet.replies"
        :favorites.sync="tweet.favorites"
        :auth-user="authUser"
    />

    Then in the JavaScript section:

    // src/components/Tweet/Tweet.vue
    import TweetReactions from '@/components/Tweet/TweetReactions'
    
    components: {
        TweetReactions
    },

    Users can now favorite and unfavorite tweets:

    Chimezie Enyinnaya

    20 posts

    Software Developer [PHP Laravel JavaScript NodeJS AdonisJS VueJS] | movie lover | run http://openlaravel.com