Creating NodeJS modules with both promise and callback API support using Q
Development | Tihomir Kit

Creating NodeJS modules with both promise and callback API support using Q

Monday, Jul 7, 2014 • 1 min read
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.

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!