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());
});