1

I've read through a lot of different articles on promisejs but can't seem to get it to work for my code. I have async code that works and does what I need but it's very long and doesn't look as clean as it could with promise.

Here's the two links I've been really looking into: http://jabberwocky.eu/2013/02/15/promises-in-javascript-with-q/ and https://spring.io/understanding/javascript-promises.

mainCode.js

accountModel.findOne({username: body.username}, function(err, usernameFound) {
    console.log("here");
    if (err) {
        console.log(err);
    } else {
        console.log("here1");
        anotherClass.duplicateUsername(usernameFound, function(err, noerr) {
            if (err) {
                console.log("error");
                res.status(409).send("username");
            } else {
                console.log("here2");
                accountModel.findOne({email: body.email}, function(err, emailFound) {
                    if (err) {
                        console.log("error2");
                    } else {
                        console.log("here3");
                        console.log(emailFound);    
                    }
                });
            }
        });
    }
});

// anotherclass.duplicateUsername

anotherClass.prototype.duplicateUsername = function(usernameFound, callback) {
    if (usernameFound) {
        callback(usernameFound);
    } else {
        callback();
    }
}

current promise code (in mainCode.js):

var promise = userModel.findOne({
    username: body.username
}).exec();

promise.then(function(usernameFound) {
    console.log("usernameFound")
    return userCheck.duplicateUsername(usernameFound);
}).then(function(usernameFound) {
        console.log("NOERR:" + usernameFound + ":NOERR");
        console.log("noerror");
        return;
    }, function(error) {
        console.log(err);
        console.log("error");
        res.sendStatus(409);
        return;
    });

When I run my promise code, it goes to duplicateUsername, does callback() but then doesn't print anything in the promise code.

user1883614
  • 905
  • 3
  • 16
  • 30
  • 1
    looks like you need to promise-ify the `duplicateUsername`. It needs to return a promise as well, instead of executing a callback. – Davin Tryon Feb 14 '15 at 22:45
  • But none of the examples in the links had that? Also, how would I go about doing that? – user1883614 Feb 14 '15 at 22:46
  • Instead of executing a callback, you would need to do a `q.resolve` or a `q.reject` and then return the deferred promise. – Davin Tryon Feb 14 '15 at 22:48
  • Something like [this](http://runnable.com/Uwy94JUNkq1PAACc/q-deferred-rejection-for-node-js)? – user1883614 Feb 14 '15 at 22:50
  • @user1883614: are you looking for http://stackoverflow.com/q/22519784/1048572? – Bergi Feb 15 '15 at 13:57
  • #3 in the solution is what I am going for however... how do I use that async function now? Would I just do getStuffAsync(param).then(function(err) {// do something}, function(data){// do something}); ? Actually, how would I convert my code into that format in the first place? I'm assuming getStuffAsync is similar to my dupliateUsername async function. – user1883614 Feb 15 '15 at 18:01

2 Answers2

0

duplicationUsername needs to return a promise, otherwise the promise chaining will get the value returned from calling callback (which would be undefined).

Something like this should work:

anotherClass.prototype.duplicateUsername = function(usernameFound) {
    var deferred = Q.defer();
    if (usernameFound) {
        deferred.resolve(usernameFound);
    } else {
        deferred.reject();
    }
    return deferred.promise;
}
Davin Tryon
  • 66,517
  • 15
  • 143
  • 132
  • I did that but it doesn't seem to do much? If usernameFound is null, then it shouldn't be calling function(err) but that's what it's doing. How do I deal with the promise? – user1883614 Feb 15 '15 at 01:02
  • Should I change the promise code in mainClass.js as well to accommodate for the change in duplicateUsername? – user1883614 Feb 15 '15 at 05:57
  • That was almost it. I needed to add: deferred.promise.nodeify(callback); to fix it. – user1883614 Feb 19 '15 at 04:38
0

So it seems like I needed to "promisify" my own functions before I could use them.

Here's how I did it with Q:

var Q = require('q');
anotherClass.prototype.duplicateUsername = function(username, callback) {
    return new Promise(function(resolve, reject) {
        var deferred = Q.defer();

        if (usernameFound) {
            deferred.reject("error);
        } else {
            deferred.resolve("no err: duplicate username");
        }

        deferred.promise.nodeify(callback);
        return deferred.promise;
    });
}

Here's how to do it with Bluebird:

userCheck.prototype.duplicateUsername = function(usernameFound) {
    return new Promise(function(resolve, reject) {
        if (usernameFound) {
            reject("error");
        } else {
            resolve();
        }
   });
}

Then in my mainClass, I just used them by calling the methods and then .then(//blah)

user1883614
  • 905
  • 3
  • 16
  • 30