Luke Berry
Luke Berry

Reputation: 1947

Wait for Node constructor to connect to api before issuing commands

Sorry if the question title is a tad ambiguous, but I'm not entirely sure how to word it.

I'm writing an NPM module that talks to a json-rpc api - this is the current setup.

// The module
function MyModule(config) {
    // do some connection stuff here
    connected = true
}

MyModule.prototype.sendCommand = function() {
    if(connected) {
        // do command
    } else {
        // output an error
    }
}

module.exports = MyModule;

// The script interacting with the module
var MyModule = require('./MyModule');
var config = { 
    // config stuff 
};
var mod = new MyModule(config);
var mod.sendCommand;

The command won't send, as at this point it hasn't connected, I assume this is due to NodeJS' asynchronous, non-blocking architecture and that I perhaps need to use promises to wait for a response from the API, where would I implement this? Do I do it in my module or do I do it in the script interacting with the module?

Upvotes: 0

Views: 876

Answers (2)

don't use promises, use node's programming model where you don't "call functions" but you "call functions with a result handler for dealing with the data once it's actually available":

MyModule.prototype.sendCommand = function(handler) {
  if(connected) {
    // run stuff, obtain results, send that on:
    handler(false, result);
  } else {
    // output an error, although really we should
    // just try to connect if we're not, and say
    // there's an error only when it actually fails.
    handler(new Error("ohonoes"));
  }
}

and then you call the function as

var MyModule = require('./MyModule');
var mod = ...
mod.sendCommand(function(err, result) {
  // we'll eventually get here, at which point:
  if (err) { return console.error(err); }
  run();
  more();
  code();
  withResult(result);
});

Upvotes: 0

jfriend00
jfriend00

Reputation: 707476

You will need to use either a callback or promises or something like that to indicate when the connection is complete so you can then use the connection in further code that is started via that callback.

Though it is generally not considered the best practice to do asynchronous stuff in a constructor, it can be done:

function MyModule(config, completionCallback) {
    // do some connection stuff here
    connected = true
    completionCallback(this);
}

var mod = new MyModule(config, function(mod) {
    // object has finished connecting
    // further code can run here that uses the connection
    mod.sendCommand(...);
});

A more common design pattern is to not put the connecting in the constructor, but to add a method just for that:

function MyModule(config) {
}

MyModule.prototype.connect = function(fn) {
    // code here that does the connection and calls
    // fn callback when connected
}

var mod = new MyModule(config);
mod.connect(function() {
    // object has finished connecting
    // further code can run here that uses the connection
    mod.sendCommand(...);
});

Upvotes: 1

Related Questions