4

How do I "promisify" my own function (that lives in another directory)? Here's my code:

// app.js

// include database
var mongo = require('./mongo');
var promise = require('bluebird');
var u = require('./util.js');
var mongo.connect = promise.promisify(require(mongo.connect));

// connect to database

var ago = new Date(new Date()-60000); // 10m ago
var scope = {size:0.01};

mongo.connect()
.then(
  mongo.endor.mapReduceAsync(u.mapTile, u.reduceTile,{
  out: {replace:'deathstar'}, scope:scope,
  query: {time:{$gte:ago}}, finalize:u.finalTile}))
.then(deathstar.find({},{fields:{_id:0, value: 1}})
  .toArray(function(err, docs){
    endor.insertAsync(_.map(docs, function(doc){return doc.value;}),{w:1});
  )
);

And here's the other file

// mongo.js

var promise = require('bluebird');
var mongodb = require('mongodb');
var MongoClient = mongodb.MongoClient;
promise.promisifyAll(mongodb);

module.exports.connect = promise.method(function(){
  // database environment
  var database;
    if (process.env.NODE_ENV == 'production'){database = pro;}
    else{database = database = dev;}
  module.exports.database = database;

  // connect to database
  return MongoClient.connectAsync(database)
    .then(function(db){
      module.exports.db = db;
      promise.all([
        db.createCollectionAsync('hoth', {w:1})
          .then(function(collection){
            collection.ensureIndexAsync()
              .then(function(index){
                module.exports.hoth = collection;
                console.log(index+' hoth');
              });
          }),
        db.createCollectionAsync('endor', {w:1})
          .then(function(collection){
            collection.ensureIndexAsync({})
              .then(function(index){
                module.exports.endor = collection;
                console.log(index+' endor');
              });
          }),
        db.createCollectionAsync('alderaan', {w:1})
          .then(function(collection){
            collection.ensureIndexAsync({time:-1, location:'2dsphere'})
              .then(function(index){
                module.exports.endor = collection;
                console.log(index+' alderaan');
              });
          })
      ]).then(function(){callback(null);});
    }
  );
});

and here's the error

/Users/Josh/Development/xWing/app.js:12
mongo.connectAsync()
  ^
TypeError: Object #<Object> has no method 'connectAsync'
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
joshula
  • 535
  • 1
  • 5
  • 19

1 Answers1

3

Promises bring back the qualities of synchronous code.

Given your API is already promisified - You simply return a promise from your function and then use that.

module.exports.connect = Promise.method(function(){
    // do a bunch of stuff
    return mongo.connectAsync().then(...
});

Note the Promise.method bit isn't required, it just turns thrown errors into rejections to give you throw safety and makes sure you return a promise so it's best practice and guards you against mishaps.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • thanks for the reply, I think my code was confusing something... please take a look one more time. I attempted your solution but it's still not working... – joshula Jul 18 '14 at 20:05
  • Your `promisify` above is incorrect - you want `Promise.promisifyAll(mongodb)` rather than `Promise.promisify` on connect. Also, when you reply with "still not working" supply the outcome, what you tried with the code above and what failed (with what error and when). – Benjamin Gruenbaum Jul 18 '14 at 20:07
  • can you take one more look above? I adjusted the code... I was including some of my other code from mongo, which may have been confusing my intent. – joshula Jul 18 '14 at 20:09
  • @sf_josh oh, are you looking for http://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises ? If the other API is already using promises you can return them from functions. – Benjamin Gruenbaum Jul 18 '14 at 20:12
  • yes, but that may be overkill for me... let me just paste the raw code... and the error I get, would love to hear you thoughts... – joshula Jul 18 '14 at 20:18
  • I'm basically trying to encapsulate all database config and connect in a separate file mongo.js - and I need to control the execution of that file (i.e. connect to database before you do other stuff) in app.'s - I know how to do it in ASYNC... but I'm trying to switch to promises via bluebird for performance reasons – joshula Jul 18 '14 at 20:28