How I Found A Job With Node + Angular, Part 2: Let’s Level Some Jobs

In the previous post, I explained my frustration about seeking possible close (geographically) and awesome future employers. I started my journey towards geo aware job finding application by discussing Node.JS basics.

In this post, I would like to serve some companies that offer positions in my field, from the node web server we just created. This means, we need to retrieve them from somewhere. Aha! A database? Well, this could be anything from hard coded JS array, a file and of course – a database. Following this short presentation about using LevelDB with Node.JS I decided to use LevelDB for this tutorial. This turned to be a bad decision. While my tests on Amazon EC2 cluster went very well, installing level on a Windows machine became a sisyphic task. Simply trying

> npm install level

Will fail. Looking at the logs you can see some rants about leveldown failed installation. LevelDB is composed from 2 main packages: levelup – which provide a high level API to the DB, and leveldown which provide the low level hard core DB functions. Trying to follow the instructions on Richard’s blog by installing only levelup:

> npm install levelup

will give a wrong first impression. While the installation goes by ok, the DB will fail on first try:

c:\Dev\node\geojob>node
> var level = require('levelup');
undefined
> var db = level('./DatabaseDirectory');
LevelUPError: Could not locate LevelDOWN, try <code>npm install leveldown</code>
    at getLevelDOWN (c:\Dev\node\geojob\node_modules\levelup\lib\util.js:109:11)
    at LevelUP.open (c:\Dev\node\geojob\node_modules\levelup\lib\levelup.js:109:37)
    at new LevelUP (c:\Dev\node\geojob\node_modules\levelup\lib\levelup.js:82:8)
    at LevelUP (c:\Dev\node\geojob\node_modules\levelup\lib\levelup.js:44:12)
    at repl:1:10
    at REPLServer.self.eval (repl.js:110:21)
    at repl.js:249:20
    at REPLServer.self.eval (repl.js:122:7)
    at Interface.&lt;anonymous&gt; (repl.js:239:12)
    at Interface.emit (events.js:95:17)
&gt;

Again, because of our friend leveldown. Trying to install leveldown directly will fail as well.
There are a lot of articles discussing how to compile leveldown for Windows, but I decided to let go of LevelDB for now. This is not what I would have decided, if I was going to continue this tutorial on a linux machine, but for Windows machcouchine I needed a simpler solution.

I decided to go along with CouchDB. It has a Windows installer and the installation was a breeze. After you restart your computer, the CouchDB service will run, and you can test if your DB is working properly by pointing your browser to “http://localhost:5984/_utils/index.html”. You should see the Couch admin console.

The post title should be renamed more appropriately: “How I Found A Job With Node + Angular, Part 2: Let’s Secure Some Jobs From Our Couch”, but I left it as is because I still think node + level is an awesome solution.

Now we need to install node support for couch. There are a lot of utility packages that help connect node to couch: couchdb (promise-based CouchDB client), node-couchdb, request (which basically wrap the couch http requests), but I think nano is the easiest minimalist couch client to date.

> npm install nano

To check couch with nano, let’s run this simple test:

var nano = require('nano')('http://localhost:5984');

// clean up the database we created previously
nano.db.destroy('alice', function() {
  // create a new database
  nano.db.create('alice', function() {
    // specify the database we are going to use
    var alice = nano.use('alice');
    // and insert a document in it
    alice.insert({ crazy: true }, 'rabbit', function(err, body, header) {
      if (err) {
        console.log('[alice.insert] ', err.message);
        return;
      }
      console.log('you have inserted the rabbit.')
      console.log(body);
    });
  });
});

You should see the response:

you have inserted the rabbit.
{ ok: true,
  id: 'rabbit',
  rev: '1-6e4cb465d49c0368ac3946506d26335d' }

You can also check this with Couch administration console (aka futon). You should see the “alice” database in the list of databases, and if you drill in you will see the “rabbit” document and its content.

Now we are ready to create out jobs database. Let’s call it “geojob” and insert some job offerings into it. The job document (object) will be structured like this: location id (Hebrew name), company name, sector, number of employees, area, location Name, location area, coordinates:

node
> var nano = require('nano')('http://localhost:5984');
> nano.db.create('geojob');
> var geojob = nano.use('geojob');
geojob.
    insert({ companyname: "A company", sector: "A Sector", employees: 100, area: "North", location: "A Location", locationarea: "Area", lat: 0, lon: 0 }, 'somejob', function(err, body, header) {
      if (err) {
        console.log('[geojob.insert] ', err.message);
        return;
      }
      console.log('you have inserted the job.')
      console.log(body);
    });
> ...
> geojob.
    insert({ companyname: "Another company", sector: "Another Sector", employees: 50, area: "South", location: "Another Location", locationarea: "Area 51", lat: 0, lon: 0 }, 'someotherjob', function(err, body, header) {
      if (err) {
        console.log('[geojob.insert] ', err.message);
        return;
      }
      console.log('you have inserted the job.')
      console.log(body);
    });

Now our database should have 2 jobs:

> geojob.
   list(function(err, body) {
      if (!err) {
        body.rows.forEach(function(doc) {
          console.log(doc);
        });
   }
});
> { id: 'somejob',
  key: 'somejob',
  value: { rev: '1-6fa32fe79461b0743ce9a0ef667b14c3' } }
{ id: 'someotherjob',
  key: 'someotherjob',
  value: { rev: '1-bbfa44377ce9ed50a69f7fdef8db7bc4' } }

So it seems everything works as planned. I’ve created a script that will read my jobs (maintained in a csv file) and populate the database (I leave you as exercise to use ‘fs’ and ‘nano’ and accomplish this).
In the next post we will start to use this information.

How I Found A Job With Node + Angular tutorial series:

Part 1: Let’s Do Some Node
Part 2: Let’s Level Some Jobs
Part 3: The Angular Angle
Part 4: Strap The Boot
Part 5: Mind The Map
Part 6: Going Production

Leave a Reply

Your email address will not be published. Required fields are marked *