Wrapping up HapiJS with Co, Node 0.12 –harmony and Mongoose

Check out the previous post about Hapi & Co.

I will paste here the needed code to wrap up hapi and Co so you can do something like this:

reply(yield Event.create(payload))

without having to fight with promises and bad code πŸ™‚

1. Declare Hapi and co in your package.json file:

"dependencies": {
    "co": "^4.0.2",
    "hapi": "^8.0.0",
  },

2. In your index.js require co, hapi and your routes file

var Hapi = require('hapi')
var Co = require('co')
var Routes = require('./routes')

3. Add the following to the index.js before server.start():

Routes.forEach(function(route) {
    route.handler = Co.wrap(route.handler)
})
server.route(Routes)

4. Install nvmMore help
5. Install NodeJS 0.12 –

nvm install 0.12
nvm use 0.12
nvm alias default 0.12

6. cd to your projects folder and start it with:

node --harmony .

7. Now you can call reply(yield SomePromise.getSomething()) and everything should be fine πŸ™‚

Another way to implement point 3 is to add the following to the server object:

server.decorate('reply', 'co', function (handler) {
    this.response(Co(handler))
})

And now you must call

reply.co(EventHandler.getAll())

Mongoose & Co

1. To work with mongoose you will needed to declare the development version in your package.json file:

"dependencies": {
    "co": "^4.0.2",
    "hapi": "^8.0.0",
    "mongoose": "4.0.0-rc1",
    "mongoose-timestamp": "~0.2.0"
  }

2. Mongoose-timestamp is a plugin to add the createdAt and updatedAt fields. You may not need to use it.
3. Don’t forget to use “npm install” to update your packages after you enter them in the package.json file
4. The tricky part about Mongoose is not to forget that there are cases when it will not return a promise so “yield Model.find({})” will <strong. So the mongoose team added the exec() method which returns promise so you can write: “reply(Model.find({}).exec())” and everything will be ok. πŸ™‚
5. That is all πŸ™‚

So now you stop fighting promises and have code like:

var apps = yield App.find({}).exec()
var appWithVote = yield App.findById(appId).populate("votes").exec()
var existingApps = yield App.find( { package: { $in: packages } } ).exec()

var existingAppsPackages = []
for(var i in existingApps) {
  existingAppsPackages.push(existingApps[i].package)
}

console.log(apps)
console.log(appWithVote)
console.log(existingApps)

You may also like...