/ NodeJS

NodeJS — A beginners guide to a lot of stuff. Part 2

Check out part one of the series
Enough with the introductions. Let’s start getting busy.

What you will need

You will need node installed on your machine or on a Virtual Machine. You can find zillions of “How to” on the web… if you need help, start here.
An editor is handy. I like two editors very much, VSCode and Atom (VSCode is my primary editor though, as I have found it runs lighter on my old Linux machine).
Finally, have some system you wish to build. If you are fresh out of ideas, a simple ToDo application (which seems to be the new “Hello World” of technologies) will be just fine.

Enough of yada yada, let’s get cracking

El Biggo Problemo

Let’s say your system needs categories, with an ID, a name and a slug.
You decide that your system is running on MongoDB, so you go and create the schema for mongoose, create the model, implement the API using the model and even do some Mocha and ChaiHTTP Tests to ensure that all is OK.

As your system evolves, you start noticing that you have a very high number of relationships between models. Queries are starting to get sluggish and more and more complex. You made a bad judgment call, your database should not be a DocStore, it should have been a Relational Database!

What now? You need to go back into your code, replace the model, fix up you objects, correct you callbacks, re-write your tests… argh!!

A couple of days gone to waste, or, if you are like T. Edison, you learnt a way of not doing Node development!

Let’s go about fixing that with a small word: Interface

What is an interface?

Basically, it determines what you can do with a specific object.
Let’s go back to our Category thingy; Let’s think of what we need to do with fetch all categories, fetch a single category, insert a new category and finally edit, delete and search for a category.
With that, we have the basics for creating an object that can serve as a blueprint for a category. Based on this blueprint, we can build(implement) objects that follow the same Interface, same methods and same inputs.

Javascript does not have, like Java, Interfaces, but, that does not mean we cannot implement them. Let’s get started with our category:

var ICategoryRepository = {
  getAll:function(callback){},
  get: function(id, callback){},
  save: function(category, callback){},
  edit:function(id, category, callback){},
  delete:function(id, callback){},
  query:function(query, callback){}
}
module.exports=ICategoryRepository;

This does not do much on it’s own, but it gives us a couple of important things: it describes how our CategoryRepository should behave.

Let’s create a mock implementation of our Category repository so that we can write our tests. We will go with the getAll and getId methods first, I’ll show you the code, then, to the best of my ability explain what I am doing:

var ICategory = require('../interfaces/models/ICategoryRepository');
var CategoryMock = function(sampleData){
  this.sampleData = sampleData;
}
CategoryMock.prototype = Object.create(ICategory);
CategoryMock.prototype.getAll = function(done){
  //done expects two parameters, Err and Result
  return done(null, this.data);
}
CategoryMock.prototype.getId = function(id, done) {
  try{
    for (let row in this.data){
      if (this.data[row].id===id){
        return done(null, this.data[row]);
      }
    }
    throw Error('ID no found');
  }catch(err){
    return done(err, null);
  }
}
module.exports = CategoryMock;

OK, that does seem like a mouth-full. Let’s break it up.
We create a constructor function that has injected into it (receives) some sample data.

We then set the prototype of the object to the interface object (so effectively we are defining which methods are available for this object).

Finally, we are overloading (replacing) the getAll method with a new implementation for our specific use case — in this example, we are returning all the sample data inside our callback. I always return two values —err and result (as stated on the comment), this will become clear later on.

We also overload the getId method. Notice that we pass the same parameters that are expected on the interface id and done (my callback function). On this method, we basically read through the array of sampleData, if we find the object ID we are looking for, we return the callback with a null for errors and the row in question. If not, we throw an error, and return the error and a null to our callback.

So far so good?

Let’s test this bugger and see what we’ve got so far.
I personally like to use Mocha and Chai for my testing. Again, you can google around, but it’ s pretty straight forward to setup.
Next article, I will go into my test suite, and a couple of tricks I have learnt, that make testing a breeze.

Continue onto Part 3

Gregory Brown

Gregory Brown

Baker, cake designer, cook and just by chance, a full featured developer that is passionate about technology.

Read More