Menu

Troubleshooting, Coding and Comic Books

{Code Walkthrough} Online Kanban Board with Nashorn

Hello hello my fellow Nashornians, this week I present to you a quick Code Walkthrough on my latest invention: The Online Kanban Board. I’m sure there must be thousands like this out there (better ones I bet) but I decided to code my own when some Support colleagues from work were trying to find out what one of the team members was working on, beyond being the best “tasks bottleneck” detector, this is a nice resource to help everyone to talk about their activities in a good old stand-up meeting, but be aware that meetings can be dangerous. Use the KISS (Keep It Simple, Stupid) principle, get everyone in a room, decide among each other who’s gonna be the “meeting leader”, organize the post-its for each person and go around the room asking these 3 little questions:

What did you achieve yesterday?

What will you do today?

Are you blocked or do you need assistance?

Don’t let the meeting take more than 15 minutes.. if you need to do some code review or brainstorm, schedule other meetings for that, define the agenda and… wait, I’m digressing too much on this subject, let’s see some CODE!😀

—

Ok, I won’t dive too much on the ‘httpsrv.js‘, it is just a humble upgrade to the one Jim Laskey wrote in his official Nashorn Blog, I just took his code and added some stuff that wanted because command-line I/O wasn’t interesting enough for me to start playing with it, so my version is handling HTTP POST requests and I’m loading a controller.js file to handle non-static-file requests, I will go through the interesting bits later on.

So, let’s start with the HTML and CSS, at the end of this section we should see an interface like this:

Here’s how the files were structured:

The HTML is quite simple, as you can see, I’m just linking a bunch of stuff that I used to create a good client-side experience ( JQuery-UI for the Draggable and Editable components), then there’s the ‘mykanban.js’ file where I have the code that will be sending the AJAX requests, the post-its will be loaded within the ‘container’ div.

The client-side Javascript starts by loading all the post-its that are stored in the MongoDB database, it sends a GET AJAX request to the controller which loads the MongoDAO.js and call the ‘readAll()’ function, once the json data is retrieved, it takes the data and call the ‘addpostit()’ function so the draggable div elements can be created, each one with their respective id, task String and position.

Here’s the controller.js, it handles the data that comes from the client-side and process the Mongo-related actions:

load(“./mykanban/dao/mongoDAO.js”);

function Controller() {

this.readData = function() {

return “{ \”postits\” : [” + mongoDAO.readAll() + “]}”;

}

this.deleteData = function(params) {

print(“to be deleted: ” + params);

try {

mongoDAO.delete(params);

}catch(e){

print(‘Error while deleting the object from Mongo: ‘ + e.printStackTrace());

}

return generateResponse(mongoDAO.readAll());

}

this.processData = function(params) {

print(params);

try {

mongoDAO.create(params);

}catch(e){

print(‘Error while saving the object into Mongo: ‘ + e);

}

return generateResponse(mongoDAO.readAll());

}

function generateResponse(data) {

var HTML = ” “;

return HTML;

}

}

It would be cool to come up with some dependency injection mechanism here.. but let’s leave that for later. The DB Persistence layer is comprised of two files ‘MongoDAO.js’ and ‘MongoConnector.js’, the first one loads the second because the connector contains all the “imports” (MongoDB driver) and, now here comes the coolest part, the ‘mongoConnector’ function, which creates a singleton in Javascript through a closure:

var mongodb = Packages.com.mongodb;

var MongoClient = mongodb.MongoClient;

var MongoException = mongodb.MongoException;

var WriteConcern = mongodb.WriteConcern;

var DB = mongodb.DB;

var DBCollection = mongodb.DBCollection;

var BasicDBObject = mongodb.BasicDBObject;

var DBObject = mongodb.DBObject;

var DBCursor = mongodb.DBCursor;

var ServerAddress = mongodb.ServerAddress;

var JSON = mongodb.util.JSON;

var Arrays = java.util.Arrays;

var mongoConnector = (function() {

//Singleton

var mongoConnector;

function init() {

return {

getDB : function() {

var mongo = new MongoClient(“localhost”);

var db = mongo.getDB(“test”);

return db;

}

}

}

return {

//Get the singleton instance or create a new one

getInstance : function() {

if(!mongoConnector) {

mongoConnector = init();

}

return mongoConnector;

}

}

return mongoClient;

})();

For those of you who don’t know what a closure is (I won’t even ask about Singleton, just google “Design Patterns” to learn about it), I will try to explain it here (I want to highlight this concept because, to be honest, even though it might seem silly to many programmers, it took me a while to understand it), anyone can memorize “It is a function that returns an inner function that stores the variables defined in the outer function” but comprehending is a whole different story.

In my case here, I didn’t want to create an instance of my mongoConnector for every connection (hence the Singleton), but that’s where Javascript makes everything easier, the ‘getInstance()’ function stores the ‘mongoConnector’ variable that was declared outside its own block of code, notice that the ‘mongoConnector’ function (outer function) is executed only once, it is an IEF (Immediately Executed Function) because it calls itself right after its defintion, i.e., (function() {…})(); , it returns the inner function with the getInstance() function and, at this point, the init() function no longer exists, we won’t have any other expensive operation here, thanks to the closure.

The greatest thing about this project is that it’s all JSON, end-to-end, even the create/update/delete operations involve the creation of a json formatted ‘postit’ data that gets sent to the controller and processed by MongoDB (JSON.parse()), here’s the function from ‘mykanban.js’ that creates a new post-it:

That’s it. if you want to try it out just download the code from github, install MongoDB in your machine, start the database server (just run ‘mongod’, you might need to specify where the files will be stored, in this case use the –dbpath parameter, e.g., ‘mongod –dbpath /var/db/data’) and finally (assuming you have the JDK8 or the OpenJDK built in your machine with Nashorn) start the HTTP Server to see your Kanban board implemented with Nashorn, here’s the command: