Friday, August 2, 2013

async - Avoiding the callback hell in node.js


The slides and code examples linked from this post explain how to avoid deep nesting of function calls generally referred to as "callback hell" when working with node.js. Node newbies often run into "callback hell" when they try to build something non-trivial. I have experienced these problems myself and started looking for ways around it. I found this library called async @ https://github.com/caolan/async which provides a neat API to overcome the problem.
Below are the link to the slides on how to use the async library as well as introduction with code examples on how to use the different functions provided by async presented at node.js Melbourne meetup on 31st July, 2013.


Wednesday, April 24, 2013

Tweet Plotter slide at node.js Melbourne meetup.

I had the opportunity to demo the Tweet Plotter at node.js meetup today. The reaction from the group was awesome.Here is the quick overview slide on paper shared with the group.

Fork it at Github if you want to test drive -  https://github.com/amithn/tweet-plotter.git




   Below is the snapshot of Tweet Plotter.





Monday, April 22, 2013

Tweet Plotter - Plotting tweets in real-time on Google maps using node.js + socket.io + jade + stylus + bootstrap

This was my weekend hack to plot tweets in real-time on Google maps using node.js + socket.io.
Fork it at Github if you want to test drive -  https://github.com/amithn/tweet-plotter.git


See it in action - this video shows tweets (with the filter "India" being plotted on Google maps in real-time.You can hover over the marker to see the names of tweeter's and click on the marker to actually read the tweet.





Sunday, April 14, 2013

Node.js testing with Mocha and should.js

I noticed that i was doing a lot of exploratory testing in node.js. I wanted to checkout how easy/difficult would it be TDD. This is what i found. There is a decent testing framework called Mocha.

Testing node.js modules with Mocha Following is the module under test, which is just there as a test really. My barebones math class is below.

Following are the tests for the MyMath module. Neat and simple. I have used the should module to do the assertions.

Finally, this is how you can run the tests using mocha.


 

To install Mocha and should you could use the Node package manager.To read further please head to Mocha

Friday, April 12, 2013

Javascript gotcha - How to convert an argument (variable) to an Object key!

In one of the brown bottle session's a colleague of mine had this presentation on "Javascript Gotcha's" which i thought was pretty interesting. I recently came across one of them :

Here is the question i posted on StackOverflow : http://stackoverflow.com/questions/15951406/javascript-how-to-convert-argument-to-a-key

Friday, April 5, 2013

Parsing uploaded CSV file using node.js, Express

This afternoon i was looking for a CSV parser in node.js. This was the easiest one to use.
https://github.com/koles/ya-csv

Following is the code for parsing the CSV file. I'm using Express to build a Web app. If you would like to read more about Express go here http://expressjs.com/

First, install the parser using the following command:

npm install ya-csv

npm is used for dependency management for node.js.

My sample CSV file looks like so :

Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666
Kukku, Nambiar, kukku@kukku.com, +01123457666

Following is my html code used for the file upload:

<form action="/upload/group" method="POST" enctype="multipart/form-data">
<input type="file" name="groupfile">
<button type="submit" class="btn">Submit</button>
</form>

All the files uploaded (in this case only one called groupfile) is available in the HTTP req variable
called req in this example.

var csv = require('ya-csv');


app.post('/upload/group', function(req, res) {
        console.log('File name is ' + req.files.groupfile.name);
        console.log('File size is ' + req.files.groupfile.size);
        console.log('File size is ' + req.files.groupfile.path);
        var reader = csv.createCsvFileReader(req.files.groupfile.path, {
                                                'separator': ',',
                                                'quote': '"',
                                                'escape': '"',  
                                                'comment': ''
                                             });
        reader.addListener('data', function(data) {
                console.log(data);
        });
  });



Following is the output when i upload a file called test.csv 

File name is test.csv
File size is 461 
File size is /tmp/4289570db2af84a242ea7f995a3aa01a
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]
[ 'Kukku', ' Nambiar', ' kukku@kukku.com', ' +01123457666' ]


The above code creates a CSV reader using ya-csv.  Note that  req.files.groupfile.path points to the path of the uploaded file on the disk. It is saved automatically and you do not have to save it yourself. 


var reader = csv.createCsvFileReader(req.files.groupfile.path, {
                                                'separator': ',',
                                                'quote': '"',
                                                'escape': '"',  
                                                'comment': ''
                                             });

Thast's it, when a record (a line) is read the 'data' listener is triggered and you get each row from the csv file. You can hook up the 'end' event listener as well to detect the end of the file like so:


reader.addListener('end', function() {
                console.log('Closed event received now');
        });

You would need to hookup the 'end' event listener to render a view to the user like below:


reader.addListener('end', function() {
                res.render('success_csv_upload', {message : "Successfully consumed the CSV file");
        });

Otherwise, the page would just keep spinning there waiting for a response. Make sure you have a view with that name otherwise this call will fail. The point i'm trying to make is that the 'end' event listener signals the end of CSV file parsing and time to get back to the user. 

This is a paradigm shift in the way we write code if you are not coming from a event driven style of programming background. But i'm sure you will get used to it in a while playing with node. I find node to be a great framework for web applications. I haven't explored it extensively, but i think it has a promising future.


I will be publishing this source on github so that you can clone the entire web application which demonstrates the file upload and CSV parsing.


Followers

About Me

I'm a software developer with interests in Design Patterns, Distributed programming, Big Data, Machine Learning and anything which excites me. I like to prototype new ideas and always on the lookout for tools which help me get the job done faster. Currently, i'm loving node.js + Mongodb.