Sunday, February 21, 2016

Step by Step NodeJS


Let's start with traditional "Hello World" program.
Install Node.js from here

Create a new file, HelloWorld.js, add the following content.

 
console.log("HELLO WORLD");


You can see the output of your code by doing the following
 
node HelloWorld.js



Going forward we will execute each of our program the above way

A simple addition problem

Accept summation items as parameters for code. Before you consume them, check to see, if user has passed needed parameters. If not, error or return


// check for arguments passed to program
var hasArguments = function(array) {
 if(array.length > 2) {
  return true;
 }

 return false;
};

var isInteger = function(x) { 
 return Math.floor(x) === x; 
}
var isFloat = function(x) { 
 return !!(x % 1); 
}

// Get numbers from parameters
var numberFromVariable = function(param) {
 if(isFloat(param)) {
  return parseFloat(param);
 } 

 return parseInt(param);
} 

var sumOfIntegerArguments = function(array) {
 var grandTotal = 0.0;
 // start from index 2, proceed all the way to end
 for(var index=2;index


Folder Explorer

This is to filter files in a folder. We could achieve this in 2 ways. We could either put all things in file or export part of a functionality to another file. This way, we could keep the code clean

Method 1 (All in one file)

 

var fs = require('fs'),
 path = require('path');

var directoryLocation;
var filter;

var listDirectoryCallback = function(err, files) {
 for(var index =0;index 3) {
  filter = process.argv[3];
 // check for '.', if there is one, rmeove it
 if(filter[0] != '.') {
  filter = '.' + filter;
 }
}

checkAndListFolder(directoryLocation, fileStatsCallback);
})();

Method 2 (Exports logic)

By exporting certain functions into another file, we make it easier on the programs from readability perspective as well as from reusability

FolderExplorerMain.js


 
var checkAndListFolder = require('./FolderExplorer');

var listDirectoryFailed = function() {
 console.log('ERROR: This is not a directory. Please pass on directory name to explore')
};

var listDirectoryCallback = function(err, files) {
 if(err) {
  console.log('ERROR: undefined');
  listDirectoryFailed();
 }
 for(var index =0;index 3) {
 checkAndListFolder(process.argv[2], process.argv[3], listDirectoryCallback);
}


FolderExplorer.js

 
var fs = require('fs'),
 path = require('path');

var checkAndListFolder = function(directoryLocation, filter, callback) {
 fs.readdir(directoryLocation, function(err, files) {
  if(err) {
   return callback(err);
  }
  var fileList = [];

  fileList = files.filter(function(file) {
   return path.extname(file) === '.' + filter;
  });

  callback(null, fileList);
 });
};

module.exports =  checkAndListFolder;



A simple HTTP Server

A very simple, basic HTTP server that would listen on a port passed on as argument or on 1337

 
var http = require('http');
var port = process.env.PORT || 1337;

var server = http.createServer(function(request, response) {
 response.setHeader('Content-Type', 'text/plain');
 response.end('Hello World!!!');
});

server.listen(port, function() {
 console.log('Listening in port ' + port);
});



A simple HTTP client

 
var http = require('http');

if(process.argv.length <= 2) {
 console.log('ERROR: Please pass the URL to read');
 return;
}

var URL = process.argv[2];
//'http://localhost:1337/'
http.get(URL, (res) => {
 // console.log('GET response: ' + res.statusCode);

 res.on('error', (err) => {
  console.log('Error :' + err);
 });

 res.on('data', (data) => {
  console.log(data.toString());
 });

 res.on('end', () => {
  //console.log('END of data');
 });

 res.resume();
});




A simple HTTP client that streams data

 

var http = require('http');

if(process.argv.length <= 2) {
 console.log('ERROR: Please pass the URL to read');
 return;
}

var URL = process.argv[2];

http.get(URL, (res) => {
 var streamData = "";
 
 res.on('error', (err) => {
  console.log('Error :' + err);
 });

 res.on('data', (data) => {
  if(streamData.length <= 0) {
   streamData = data.toString();
  } else {
   streamData += data.toString();
  }
 });

 res.on('end', () => {
  console.log('' + streamData.length);
  console.log(streamData);
 });

 res.resume();
});



Another way of achieving streaming HTTP client

 

var http = require('http');
var bl = require('bl')

if(process.argv.length <= 2) {
 console.log('ERROR: Please pass the URL to read');
 return;
}

var URL = process.argv[2];

http.get(URL, (res) => {
 var streamData = "";
 
 res.pipe(bl(function(err, data) {
  if(err) {
   console.log('ERROR: ' + error);
  } else {
   var finalData = data.toString();
   console.log(finalData.length);
   console.log(finalData);
  }
 }));
});

A simple GET request

Do a simple GTE request from either a browser or cUrl command to see if this program handles GET request the way it should.

 
/**
 * Created by krishnan on 2/21/16.
 */
var http = require('http');
var url = require('url');
var Router = require('router');
var finalhandler = require('finalhandler');
var port = Number(process.argv[2]) || 8080;

var server = http.createServer(function(req, res) {
    router(req, res, finalhandler(req, res))
});

var router = Router();
router.route('/').get(function(req, res) {
    res.setHeader('Content-Type', 'text/plain; charset=utf-8');
    res.end('Default route - Reach out to /api/parsetime for time information.');
});

router.route('/api/parsetime').get(function(req, res) {
    var queryData = url.parse(req.url, true).query;
    res.setHeader('Content-Type', 'text/plain; charset=utf-8');

    if(queryData.iso == null) {
        res.end("ISO parameter is NULL");
    } else {
        //res.write("ISO is: " + queryData.iso + "\n");
        var date = new Date(queryData.iso);
        //res.write("New date is: " + date);
        var stringDate = "{hour: " + date.getHours() + ", minute: " + date.getMinutes() + ", second: " + date.getSeconds() +  "}";
        var jsonDate = JSON.stringify(eval("(" + stringDate + ")"));
        res.end(jsonDate);
    }
});

router.route('/api/unixtime').get(function(req, res) {
    var queryData = url.parse(req.url, true).query;
    res.setHeader('Content-Type', 'text/plain; charset=utf-8');

    if(queryData.iso == null) {
        res.end("ISO parameter is NULL");
    } else {
        //res.write("ISO is: " + queryData.iso + "\n");
        var date = new Date(queryData.iso);
        //res.write("New date is: " + date);
        var stringDate = "{unixtime:" + date.getTime() + "}";
        var jsonDate = JSON.stringify(eval("(" + stringDate + ")"));
        res.end(jsonDate);
    }
});

server.listen(port, function() {
    console.log('Listening on port: ' + port);
});



A simple POST request

We can make a simple POST request using cUrl to see if this code processes POST command as well as it should

 

var http = require('http');

var port = Number(process.argv[2]);
var server = http.createServer(function(req, res) {
 res.setHeader('Content-Type', 'text/plain');
 if(req.method === "POST") {
  var reqMessage = "";
  req.on('data', function(buffer) {
   reqMessage += buffer.toString();
  });

  req.on('end', function() {
   // console.log('User put in: ' + reqMessage);
   res.end(reqMessage.toUpperCase());
  });
 }
});

server.listen(port, function() {
 // console.log('Server listening in port ' + port);
})



A simple Socket server

A simple socket server that you can connect using 'nc' command, to see if you can connect and see things work.

 
var net = require('net');

var now = function() {
 var connectionTime = new Date();
 var dd = (connectionTime.getDate() < 10 ? '0' : '') + connectionTime.getDate();
    var mm = ((connectionTime.getMonth() + 1) < 10 ? '0' : '') + (connectionTime.getMonth() + 1);

 return connectionTime.getFullYear() + "-" + mm + "-" + dd + " " + connectionTime.getHours() + ":" + connectionTime.getMinutes(); 
}

var server = net.createServer();

if(process.argv.length <= 2) {
 console.log("ERROR: Please pass the port to listen to");
 return;
}

PORT = Number(process.argv[2]);

if(PORT <= 80) {
 console.log("ERROR: Invalid port number");
 return;
}

server.on('connection', function(conn) {
 var connectionTime = new Date();
 var dd = (connectionTime.getDate() < 10 ? '0' : '') + connectionTime.getDate();
    var mm = ((connectionTime.getMonth() + 1) < 10 ? '0' : '') + (connectionTime.getMonth() + 1);

 console.log(connectionTime.getFullYear() + "-" + mm + "-" + dd + " " + connectionTime.getHours() + ":" + connectionTime.getMinutes());

 conn.setEncoding('utf8');

 conn.on('close', function() {
  console.log('Connection closed');
 });

 conn.on('data', function(buffer) {
  process.stdout.write('Server received data: ' + buffer);
 });

 /*// var emit = conn.emit;
 // conn.emit = function(event) {
 //  console.log('Connection emitted event: %j', event);
 //  emit.apply(conn, arguments);
 // };*/
});

server.listen(PORT, function() {
 console.log('Server listening at port: %j', server.address());
});



1 comment:

  1. Dear Krishna,

    For the first Addition program, could you please post complete code... I don't see the parseFloat(), parseInt().. Being this one the first example in the NodeJS series in your blog, it would be great if it is complete.
    Thanks and keep up the great work.

    ReplyDelete