«®»
Home About Work Contact Quotes

Handling one-off events with callbacks (Node.js)

Prerequisite: JavaScript knowledge, I'd say you need to at least understand the server-client model and how the HTTP protocol works. that should be enough to get you started if you already know JS. Node installation steps can be found here - https://nodejs.org/

To demonstrate the use of callback let's make a simple HTTP server that will perform following tasks

  • Asynchronously pulling the titles stored as a JSON file
  • Pull basic HTML template, Asynchronously
  • Assembles an HTML page containing titles
  • Render this HTML page.

TODO : An HTML response from a web server that pulls titles from a JSON file and returns results as a web page.

titles.json

Create a JSON file, formatted as an array of strings containing titles of posts.

//A list of post titles.
[
"I need attention! GIVE ME SOME ATTENTION!",
"Is this a circus? Why is there a monkey wearing a suit",
"Quintessential Fairytale Weddings for under $1,000"
]

template.html

The HTML template file will include just a basic structure to insert the titles of the blog posts

<!doctype html>
<html>
<head></head>
<body>
	<h1>Latest Posts</h1>
	//% will be replaced with title data
	<ul><li>%</li></ul>
</body>
</html>

blog_recent.js

Following code will pull JSON file and render the web page.


//Load http,fs modules to create an http server and read files
var http = require("http");
var fs = require("fs");

//Create HTTP server and use callback to define response logic
http.createServer(function (request, response) {
	if (request.url!="/") {
		response.writeHead(404,{"Content-type":"text/plain"});
		response.end("Page not found!");
	}else{
		//Read JSON file and use callback to define what to do with its contents
		fs.readFile("titles.json",function (error, data) {

			//If error occurs, log error and return "Server Error" to client
			if (error) {
				response.writeHead(500,{"Content-type":"text/plain"});
				response.end("Server error :" + error);
			}else{
			  	//Parse data from JSON text
				var titles = JSON.parse(data.toString());

				//Read HTML template and use callback when it’s loaded
				fs.readFile("template.html",function (error, data) {
					if (error) {
						response.writeHead(500,{"Content-type":"text/plain"});
						response.end("Server error :" + error);
					}else{
						var template = data.toString();

						//Assemble HTML page showing blog titles
						var html = template.replace("%",titles.join("</li><li>"));

						//Send HTML page to user
						response.end(html);
					}
				});
			}
		});
	}
//Listen on port 5000, IP defaults to 127.0.0.1
}).listen(5000,"127.0.0.1");

//Put a friendly message on the terminal
console.log("Listening to http://127.0.0.1:5000");

Now as you can see above code has three levels of callbacks, the more cluttered your code looks, and the harder it is to refactor and test. By creating named functions that handle the individual levels of callback nesting, you can express the same logic in a way that requires more lines of code but it will be easier to maintain and test. Next post will give an example of reducing nesting by creating named functions.