If you’re building your own NodeJS library and you like using Promises, chances are you’ll want to implement your module API through promises.

However, you might also want to support the error-first callback pattern as well, for all the developers out there who prefer to use the standard NodeJS approach. Since Q is currently one of the most popular and well rounded JS promise libraries with NodeJS support, in this post we’ll be using Q to implement a module function that will support dual promise/callback API’s.

// dual-module.js
var Q = require('q');

module.exports = {
    getFullName: function (firstName, lastName, callback) {
        var deferred = Q.defer();

        if (firstName && lastName) {
            var fullName = firstName + " " + lastName;
            deferred.resolve(fullName);
        }
        else {
            deferred.reject("First and last name must be passed.");
        }

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

The getFullName() function will always return a promise and if passed a callback (assuming it’s a NodeJS-style callback), deferred.promise.nodeify() will register it. So, callback is an optional parameter.

The getFullName() module function can now be used either through a promise…

var DualModule = require('dual-module');

DualModule.getFullName("John", "Doe")
.then(function (result) {
    // result returns "John Doe"
})
.fail(function (error) {
    // error returns error message if either first or last name are null or undefined
});

… or through the standard NodeJS error-first callback:

var DualModule = require('dual-module');

DualModule.getFullName("John", "Doe", function (error, result) {
    // error returns error message if either first or last name are null or undefined   
    // result returns "John Doe"
});

That’s it, happy module writing!

More articles

Your opinion matters!

comments powered by Disqus