0

In the code below when i call using ninvoke the "then" part does not get executed. The result is as follows

calling thru a function that uses ninvoke dbConnect --> Success: Connected to db!

calling directly dbConnect --> Success: Connected to db! 2222222 - After Called Directly

Why is that?

"use strict";

var theQ = require("q");
var pg = require('pg');
var dbUri = "postgres://postgres:user123@localhost:5432/postgres"; //postgres uri
var client1 = new pg.Client(dbUri);
var client2 = new pg.Client(dbUri);

function dbConnect(dbClient, tag) {
    //var myName = arguments.callee.toString().match(/function ([^\(]+)/)[1];
    var deferred = theQ.defer();
    dbClient.connect(function(err, result) {
        if (err) {
            console.error("\n" + tag + "\ndbConnect --> Failure: could not connect to db!!!!");
            deferred.reject();
        }
        else {
            console.log("\n" + tag + "\ndbConnect --> Success: Connected to db!");
            //results[]
            deferred.resolve();
        }
    });
    return deferred.promise;
}

function myTestDB(dbClient, tag) {
    return theQ
        .ninvoke(dbConnect(dbClient, tag))
        .then(function() {console.log("333333 - Called after ninvoke");});
}

//main line
myTestDB(client1, "calling thru a function that uses ninvoke");
dbConnect(client2, "calling directly").then(function() {console.log("2222222 - After Called Directly");});
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 1
    Note that this code `.ninvoke(dbConnect(dbClient, tag))` is **calling** `dbConnect` immediately, and passing its return value into `ninvoke`. Exactly the way `foo(bar())` *calls* `bar` and passes its return value into `foo`. So I suspect this isn't quite what you meant, since both lines of code call `dbConnect` inline, not later. – T.J. Crowder May 26 '14 at 16:47
  • Yeah, did you mean `.ninvoke(dbConnect,dbClient,tag)` ? – Benjamin Gruenbaum May 26 '14 at 16:48

2 Answers2

2

Life is too short for manual promisification

"use strict";
var Promise = require("bluebird");
var pg = require('pg');
Promise.promisifyAll(pg.Client.prototype);
var dbUri = "postgres://postgres:user123@localhost:5432/postgres"; //postgres uri
var client1 = new pg.Client(dbUri);
var client2 = new pg.Client(dbUri);



client1.connectAsync()
    .then(function() {
        console.log("connected to bg, begin query");
        return client1.queryAsync("SELECT * FROM example")
    })
    .then(function(result) {
        console.log("query complete, first row: " + JSON.stringify(result.rows[0]));
    })
    .error(function(e) {
        console.error("failed to connect");
    });
Esailija
  • 138,174
  • 23
  • 272
  • 326
0

Firstly you are first calling dbConnect and then calling the result with ninvoke. This is wrong.

I think you need to read this section of q again: http://documentup.com/kriskowal/q/#tutorial/adapting-node

Basically nfcall, nfapply, npost, ninvoke functions are meant to create a promise by calling a nodejs callback style function. In your case function dbConnect, is not following node.js callback, but returning a promise.

dbClient.connect is following node.js callback style. You can use nfinvoke to call it and get a promise out of it like this:

Q.ninvoke(dbClient, 'connect')
  .then(function() {console.log("We used ninvoke");})
  .catch(function (err) { console.log('we got the error!') });

The above will call connect method of dbClient and return a promise, which almost equal to what dbConnect does.

Farid Nouri Neshat
  • 29,438
  • 6
  • 74
  • 115
  • Thanks first of all! I understand the problem with calling dbConnect. Also I tried the way you suggested and it seems to work. But, how to catch the failure to connect when you write like this. Also, I have a few questions though. Is there a way to write nodejs style function? Good documentation anywhere. – user3677016 May 27 '14 at 14:31
  • I added error handling too. Check this question: http://stackoverflow.com/q/7116722/774086 – Farid Nouri Neshat May 27 '14 at 17:12