Create a like button with a like-counter

Today I’ll be talking about how to 1) create a like button, 2) count the number of likes, and 3) appending the button and results to the DOM.

Say for instance we want to build an app that displays a random activity from an API.

First we call fetch, passing the API URL as an argument (as a string, wrap the URL in quotes). We then call .then(), passing the response from our fetch as an argument, and calling json()on our response (JavaScript Object Notation). Calling json()on our response allows us to write JavaScript code for our response object, so that we can do some DOM manipulation! Finally, we use a second .then()call, passing the jsonified object as a parameter for its function. Now that we have access to the API object, we can write our JavaScript for DOM manipulation.

What do we want to do with our jsonified object? We want to display a random activity to the DOM, and we want to add a like button to it. So, we can write a function for that. Let’s call it displayActivities(). Our function will take a parameter, of which we can pass our jsonified object, so let’s call the parameter object.

In our HTML, let’s create a <div> where we will store the activities.

Now we’re ready to start writing code for our displayActivities() function.

First we grab our activity list <div>, and store it into a variable.

Next we can create a paragraph element which will store the activity. We do this by setting this paragraphs’ innerHTML to object.activity. With object.activity, we are accessing whatever object we pass into our function (in this case our jsonified object), and accessing its activity property. The value of this activity property is the random activity string which we want posted to the DOM. This activity property is defined in this specific API, so if you are using a different API, the key/property name may be different. Be sure to check your API documentation for its specific keys and values. In conclusion, with boredomActivity.innerHTML = object.activity, we are saying this newly created paragraph holds the random activity string.

Now let’s create our like button, and set its textContent to "like".

We’ll need to create another element to display our like count (how many times an activity was liked). Let’s make it another <p> or paragraph element.

Now we should create a variable which stores the number of likes, named likes.

Here with our variable declaration we are using ‘let’ instead of ‘const’. There is good reason for this! Const variables cannot be redeclared or reassigned, and let variables cannot be redeclared, but they can be reassigned. We use ‘let’ if the value of a variable is expected to change (it is commonly used in loops for this reason). In our case, we are expecting our like value of 0 to change. We expect it to increase by 1, each time our like button is clicked. So by declaring our like variable with let, we are telling the JavaScript engine that it’s okay for this variable’s value to change. If we used const, we would receive an error, because const variables cannot be reassigned.

Now we can write our code for counting likes. Why not make it a function! Let’s name it incrementLikes(). This function will be nested inside our displayActivities() function, so that it can access the variables inside displayActivities(). Let’s take a look our updated displayActivities() function:

Here in our increaseLikes() function, we access our like variable and say we want like to equal like + 1. We can use the increment operator ++ for this, which adds one to its operand and returns a value.

Now we just need to set the innerHTML of our likeCount paragraph to our likes variable (containing the number of likes, which we’ve just incremented).

However, we can do better. The code above would result in only a number being displayed upon clicking on the like button. So let’s use string interpolation to add a string at the end, so instead of just a number being displayed, we would have a number plus “likes”. Our code would then result in something like “ 4 likes” or “5 likes” being displayed, instead of just “4” or “5”. Rewrite the above code as follows:

There is still one minor problem though. When a user clicks the like button for the first time, it’s going to display “1 likes”, which is grammatically incorrect. Not to worry, there’s an easy fix for it! We can use a simple if/else statement.

We can use the === , the strict equality operator here, because we know that our likes variable containing the number of likes will be a number, and here we’re comparing likes to another number: 1. We know that the likes variable contains a number because we started our counter at 0 , meaning we initially declared likes, we set its value to equal 0. So since both comparisons are of the same type (they are both numbers), we don’t need to worry about type coercion here. If we didn’t know that both operands were going to be of the same type, we could use the equality operator == , which would attempt to convert the operands to the same type before the JavaScript engine compares them. Since we can use the === strict equality operator, we should use it.

Our updated displayActivities() function with our increaseLikes() function nested inside, should now look like this:

Now that we have all of our code written for what we’d like to happen when a user clicks the like button, let’s add our event handler to make it work.

We attach the event handler to our likeButton with likeButton.addEventListener(). The first parameter of our event handler is the specified event. In our case it’s the ‘click’ event (there are many other types of events). The second parameter of our event handler is a function, which does the work we want when a user clicks the button. Notice that we haven’t invoked our increaseLikes function with a () at the end. The reason for this is that we only want the increaseLikes function to be called once the button is clicked. If we added the () after increaseLikes in our event handler, the increaseLikes function would immediately be called, before the click event. We use a callback function so our event handler waits for the click to invoke its function.

To complete our displayActivities() function, we need to append our likeButton and likeCount to our boredomActivity variable (the paragraph element we created earlier, which will hold each activity), and then append boredomActivity to our activityList variable (the <div> element which will contain all the activities). We can use node.appendChild() for this, which will add a node to the end of the list of children of a selected parent node.

Here we’ve appended the likeButton and likeCount nodes to the parent node of boredomActivity, and then we’ve appended this boredomActivity node (containing the likeButton and likeCount nodes) to our activityList node, which now contains the random activities with their corresponding like buttons and like counts.

Our finished displayActivities() function will now look like this:

Let’s come back to our second .then() call of our fetch at the beginning of this lesson, and call displayActivities — passing in our jsonified object as its argument.

In order for our displayActivities() function to access the API of activities, we need to pass our jsonified object into it. This allows our function to access the API object’s activity property, whose value is the random activity string.

Here’s the entire code:

Hi there! I'm enrolled in Flatiron's Software Engineer boot camp. Hoping to help people with some of the programming concepts I've learned along the way!