How to Display and Update “Facebook Likes” Using Node.js
By working through the sample codes from the previous post, you might have understood the actual benefits of using Node.js. In today’s post, we’ll demonstrate a practical script that clearly shows the use of Node.js in event-based programming.
We’ll create a simple script that outputs the number of “Facebook likes” for a particular Facebook page. Additionally, we’ll include a feature that updates the number of “Facebook likes” every 2 seconds.
The output will be simple and plain, probably something like this: “Number of Likes: 2630405”. You can style it using CSS. Let’s get started!
To Give You an Idea
Before we dive into using Node.js, let’s take a moment to consider what we’d normally do with common server-side programming languages (like PHP). If you are thinking of making an AJAX call to find the number of likes every 2 seconds, you are correct. However, this may potentially increase the server overhead.
We can consider accessing graph.facebook.com, which would be a time-consuming I/O operation. Imagine 5 users accessing the same page that outputs the number of likes. The number of accesses to graph.facebook.com in 2 seconds will become 10 because everyone will update their number of likes once in 2 seconds, and it will be executed as a separate thread.
That’s not necessary with a Node.js server implementation. Only one access to the Facebook server is required, and the time to get and output the result (number of likes) can be greatly reduced.
So, how are we going to implement this? That’s what we are going to find out in the sections below.
Getting Started
Before we start, you should have Node.js installed and running on a v8 environment-supported web hosting account. Check out the topics, “Getting started with Node.js” and “Installing Node.js” in our previous article, Beginner’s Guide to Node.js if you haven’t.
In the server, we access graph.facebook.com
at an interval of 2 seconds and update the number of likes. Let’s call this “ACTION1“. We will prepare a page so that it will update itself via AJAX every 2 seconds.
Consider many users accessing the same page. For every user’s AJAX request, an event listener is attached in the server for the completion of “ACTION1”. So whenever “ACTION1” is completed, the event listeners will be triggered.
Let’s take a look at the server-side code.
The code:
var facebook_client = my_http.createClient(80, "graph.facebook.com"); var facebook_emitter = new events.EventEmitter(); function get_data() { var request = facebook_client.request("GET", "/19292868552", {"host": "graph.facebook.com"}); request.addListener("response", function(response) { var body = ""; response.addListener("data", function(data) { body += data; }); response.addListener("end", function() { var data = JSON.parse(body); facebook_emitter.emit("data", String(data.likes)); }); }); request.end(); } my_http.createServer(function(request, response) { var my_path = url.parse(request.url).pathname; if (my_path === "/getdata") { var listener = facebook_emitter.once("data", function(data) { response.writeHeader(200, { "Content-Type": "text/plain" }); response.write(data); response.end(); }); } else { load_file(my_path, response); } }).listen(8080); setInterval(get_data, 1000); sys.puts("Server Running on 8080");
Code Explanation:
var facebook_client = my_http.createClient(80, "graph.facebook.com"); var facebook_emitter = new events.EventEmitter();
We create an HTTP client to access the Facebook Graph API using facebook_client
. We also need the EventEmitter()
function, which will trigger when “ACTION1” is completed.
This will become clear in the code described below.
function get_data() { var request = facebook_client.request("GET", "/19292868552", {"host": "graph.facebook.com"}); request.addListener("response", function(response) { var body = ""; response.addListener("data", function(data) { body += data; }); response.addListener("end", function() { var data = JSON.parse(body); facebook_emitter.emit("data", String(data.likes)); }); }); request.end(); }
Function get_data
fetches data from the Facebook API. We first create a GET request using the request
method with the following syntax:
Client.request('GET', 'get_url', {"host": "host_url"});
The number “19292868552” is the Facebook ID of the page whose details we need to access. So the final page we are trying to access becomes: http://graph.facebook.com/19292868552. After making the request, we need to add three listeners to it, as follows:
- Response – This listener is triggered when the request starts receiving data. Here we set the body of the response to an empty string.
- Data – As Node.js is asynchronous, the data is received in chunks. This data is added to the body variable to build up the complete response.
- End – This listener is triggered when “ACTION1” specified above is completed. The data returned by the Facebook Graph API call is in JSON format. We convert the string to a JSON object using the JavaScript function
JSON.parse
.
You can see that a listener is attached for the event_emitter
object. We need to trigger it at the end of “ACTION1”. We trigger the listener explicitly with the method facebook_emitter.emit
.
{ "id": "19292868552", "name": "Facebook Platform", "picture": "http://profile.ak.fbcdn.net/hprofile-ak-ash2/211033_19292868552_7506301_s.jpg", "link": "https://www.facebook.com/platform", "likes": 2738595, "category": "Product/service", "website": "http://developers.facebook.com", "username": "platform", "founded": "May 2007", "company_overview": "Facebook Platform enables anyone to build social apps on Facebook and the web.", "mission": "To make the web more open and social.", "parking": { "street": 0, "lot": 0, "valet": 0 } }
The above represents the response of the Facebook Graph API call. To get the number of likes: take the likes object of the data object, convert it to a string, and pass it to the emit
function.
After this action, we end
the request.
my_http.createServer(function(request, response) { var my_path = url.parse(request.url).pathname; if (my_path === "/getdata") { var listener = facebook_emitter.once("data", function(data) { response.writeHeader(200, { "Content-Type": "text/plain" }); response.write(data); response.end(); }); } else { load_file(my_path, response); } }).listen(8080); setInterval(get_data, 1000);
Creating the server is similar to the previous tutorial with a small change. For every URL (except /getdata
), we load the corresponding static file using the load_file
function we defined earlier.
The http://localhost:8080/getdata
is the URL for the AJAX request. In each AJAX request, we attach an event listener to facebook_emitter
. It is similar to addListener
but the listener is removed after it is emitted to avoid a memory leak. If you need to check it out, just replace once
with addListener
. We also call the get_data
function once every second using setInterval
.
Next, we create the HTML page where the output displays.
The code:
<!DOCTYPE html> <html> <head> <title>Facebook Likes</title> <link rel='stylesheet'> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> </head> <body> <p>Number of Likes: <b id="content_area">Loading...</b></p> <script type="text/javascript"> var content_area = $("#content_area"); function load_content() { $.get("/getdata", function(data) { content_area.html(data); load_content(); }); } load_content(); </script> </body> </html>
Code Explanation:
The jQuery AJAX part is pretty self-explanatory. Do check out the call of the load_content
function. It looks like it runs in an infinite loop, and yes, it does. That’s how the number of likes gets updated automatically.
Each AJAX call will be delayed by the average time of 1 second because the delay in triggering each call is 1 second from the server. The AJAX request will remain incomplete for that 1 second.
So there you go – a method of delaying an AJAX response from the server to get the number of Facebook likes. Drop questions in our comment section if you have any doubts or thoughts. Thanks!