Component for liking items built with VueJs and Laravel

I'm currently delving into the world of VueJS, and for my personal project, I'm pairing it with Laravel 5.7. However, I'm facing a bit of a challenge when it comes to implementing a simple feature - a "like" button/icon.

Here's the scenario: I have a page that showcases different posts from my database. At the bottom of each post, I'd like to include a "like toggle" button, designed as an icon followed by the number of likes on that post. Initially, the button should display the data retrieved from the corresponding database table. When clicked, it should increment the displayed number by one and add a new like entry in the database.

I've created the "like" icon as a component:

<section class="bottomInfo">
 <p>
 <likes now="{{ $article->likes }}"></likes> 
 <span class="spacer"></span>
 <span class="entypo-chat"> 
  {{ $article->comments }}
 </p>
</section> <!-- end .bottomInfo -->

As you can see, I've included a <likes> tag with a now prop that holds the initial database value for likes. However, I'm unsure of where and how to store this value in my app to connect with axios for updating the likes.

Below is the component structure:

<template>    
    <span class="entypo-heart"> {{ now }}</span>    
</template>

<script>
    export default {
        props: ['now'],
        data() {
            return {
                like: this.now
            }
        },
        mounted() {
            console.log('Component mounted.');
        }    
    }
</script>

I've attempted to pass the now value to the data function within a property called like. However, when I try to access it in my main Vue instance, I receive an 'undefined' result.

The value of 'like' property is undefined

Am I approaching this correctly? How can I properly access and update this value upon click to interact with my API? I'm not seeking the specific implementation details for these tasks, but rather guidance on how to integrate them in this context. Is my understanding of the component logic accurate?

Answer №1

Adding more detail might be beneficial:

props: {
  now: {
    type: Number,
    required: true
  }
}

Instead of utilizing the data function, opt for a computed property:

computed: {
  likes: {
    get: function() {
      return this.now
    }
  }
}

However, an issue arises here.

When the user clicks like and you need to update the number of likes, you are unable to modify this.now since it is a property and properties are immutable. Vue will throw an error about mutating a property

To address this, introduce a data variable to track if the user has clicked the like button:

data() {
  return {
    liked: 0
  }
}

Update the computed property accordingly:

likes: {
  get: function() {
    return this.now + this.liked
  }
}

But what exactly are we liking? We need another property:

props: {
  id: {
    type: Number,
    required: true
  },
  now: {
    type: Number,
    required: true
  }
}

Additionally, include a method:

methods: {
  add: function() {
    //axios?
    axios.post(`/api/articles/${this.id}/like`)
      .then (response => {
        // update the `liked` property

        this.liked = 1
      }).catch(error => {
        // handle errors if necessary
      )}
  }
}

Ensure clicking the heart triggers the event:

<span class="entypo-heart" @click="add"> {{ now }}</span> 

Lastly, the likes component needs an id property from the article:

<likes now="{{ $article->likes }}" id="{{ $article->id }}"></likes> 

With these adjustments, you're on your way to mastering this feature.

Edit

Keep in mind that a user can repeatedly like the content. Implement checks in the click function to prevent this. You may also require a new prop or computed property to determine if the content was previously liked. This is not the final solution.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The navigation underline stays in place even after being clicked, and also appears below

Take a look at this js fiddle I've managed to create the underline effect on the navigation links when the user hovers over them. However, the underline only stays visible until the user clicks elsewhere on the screen. How can I make it persist as l ...

The promise is coming back as undefined

I am encountering an issue where the value returned from a promise is coming back as undefined in my template. In the getLabel function, I am receiving a label as a promise and resolving it before returning it to the title in the getMenuItems function. H ...

Create a separate function to split up the numbers provided in the prompt

I've developed a program that calculates the denomination of bank notes (2, 5, 10, 20, etc.) you need to pay based on a number you input in the prompt. Now, I'm looking to enhance this program by taking the input number from the first step and d ...

Is there a way to improve error readability in React when using webpack?

Attempting to solve the issue, I decided to make a change in my npm script. Initially, it was set to operate in production mode by default: The original script looked like this: "client": "webpack -w --config ./gen/config/webpack.config.js& ...

Enhancing user experience with Jquery datepicker and executing multiple actions on select

I am working on a form that includes a jQuery date selector and radio buttons structured in a table as shown below: <table> <tr> <td> <input type="text" id="5506_datepick_1"></input> </td> <td&g ...

How can I transfer a collection of JSON objects from JavaScript to C#?

Feeling a bit confused here. I have some Javascript code that will generate JSON data like the following: {type:"book" , author: "Lian", Publisher: "ABC"} {type:"Newspaper", author: "Noke"} This is just one example, I actually have more data than thi ...

Validate forms using jQuery with the power of ajax

Is there a way to effectively check for the existence of a username? I want to increment a variable called "form_error" if the username already exists. If "form_errors" is greater than 0, I need the code to stop and return false. However, when I use an Aj ...

Highcharts-ng allows us to create charts without using the traditional syntax such as $('#container').high

After setting up the chart's configuration in my controller, I am facing an issue. The HighCharts-ng (an angularJS directive for HighCharts) has a method that I want to implement: $scope.ohlcChartConfig = { options: {....... I ne ...

Apply a class to each element that contains the specified name attribute

I have successfully implemented a prices tab on the top of my page, with tabs for different packages at the bottom. When a user selects a certain package, only specific items from the list are visible while the others are hidden. I managed to streamline ...

Struggling to understand the javascript snippet "requiring the passport file and passing in passport as a parameter."

I am still learning the ropes of javascript and currently working on a basic login restful api using the passport middleware. I understand that when I use require('xxxxx'); I am importing a module for use. While researching online, I came across ...

I need to change a website into a string so that I can analyze it with javascript. How can I do this?

Currently, I am in the process of creating a website for my video game servers. The admin tool we use outputs the current server status in a .json format as a large text string to this specific URL: My goal is to retrieve the entire text string from the p ...

How does Vue JS's reactive computed properties get triggered when the dependent field is updated?

I created a computed field that is responsible for setting a data property called 'completed' based on whether a text field within a questionnaire has been filled out: setCompleted: function () { this.completed = this.required && ...

Material UI Alert component not appearing on screen?

Greetings, I have been working on polishing my app now that it is finally complete. I decided to enhance the aesthetics by replacing all instances of window.alerts with Alerts from MUI (since they look way better). However, for some reason, they are not sh ...

Tips for testing the onEnter and resolve functions of a ui-router state

I need help testing an Angular UI Bootstrap modal that is triggered from the onEnter function in the state below: .state("profile.index.edit.services", { url: "/edit/services/:serviceCode", parent:"profile.index", onEnter: ['$ ...

Sending data using jQuery's AJAX feature

Here is an example of the code I have: var loadUrl = 'test.php'; var dataObject = { category_id: category_id, grade_val: grade }; jQuery.ajax({ type: 'POST', url: loadUrl, data: dataObject, dataType: 'html', ...

Adding incremental values to a variable using JavaScript within the framework of jQuery and AJAX

In my JavaScript code that utilizes jQuery and AJAX, I have created a dynamic array containing multiple values for AJAX requests. The array is structured as follows: <script type="text/javascript> var array = Array("y", "y", "x", "y", "y", "y"); fu ...

Using Jquery to show element when <select> is updated

I've been struggling to make this work due to my limited jquery/js skills. My goal is to have a different message displayed for each option selected from the dropdown menu for further information. <label class="checklabel">Is it possible to re ...

Vue looping through an object containing arrays

I am facing an issue with my code where I need to iterate over multiple objects with arrays, but no return data is being displayed. Can someone please help me with my code? Here is a sample of JSON data retrieved from an API: "sections": [ ...

Enhancing Image Upload with Ajax/JavaScript: Generating Multiple Previews

I've been experimenting with an Ajax image uploader that I found on this website. Currently, I have managed to create duplicate preview images: one displayed under the input field and the other elsewhere on the page labeled as "this what you chose". H ...

Best Method for Updating a Single Scope and Setting the Others to False in AngularJS

If I have 4 fields in my view that need to be toggled open or closed when clicked, with the requirement of closing the other three, how can this be achieved without duplicate code? <div class="square red"></div> <div class="square blue"> ...