charliebrownie
charliebrownie

Reputation: 6097

Refactoring: returning a promise from a value or an existing promise

My scenario

I used to have some node.js implementation done using callbacks but I am now refactoring my code to use Promises instead - using Q module. I have the following update() function where the inner _update() function already returns a Promise:

exports.update = function(id, template, callback) {
  if (!_isValid(template)){
    return callback(new Error('Invalid data', Error.INVALID_DATA));
  }

  _update(id, template) // this already returns a promise
  .then(function() {
    console.log('UPDATE was OK!');
    callback();
  }, function(err) {
    console.log('UPDATE with ERRORs!');
    callback(err);
  });
};

My question

I would like to achieve something like the following:

exports.update = function(id, template) {
  if (!_isValid(template)){
    // how could I make it return a valid Promise Error?
    return reject(new Error('Invalid data', Error.INVALID_DATA));
  }

  return _update(id, template) // return the promise
  .done();
};

Because _update() already returns a promise, I guess changing it this way would be enough (wouldn't be?):

  return _update(id, template)
  .done();

And... what about if the condition inside the if-clause equals true? How could I refactor

return callback(new Error('Invalid data', BaboonError.INVALID_DATA));

to throw an error to avoid passing the callback into update() and handling that error (or what ever error could ever be returning _update())?

Also, calling update():

myModule.update(someId, someTemplate)
.then(function() { /* if the promise returned ok, let's do something */ })
.catch(function(err) { /* wish to handle errors here if there was any */});

somewhere else in my code:

Am I close to what I am expecting? How could I finally achieve it?

Upvotes: 2

Views: 369

Answers (1)

thefourtheye
thefourtheye

Reputation: 239453

I see only two problems.

  1. If you want to explicitly return a rejected promise with a value, you should do that with Q.reject.

  2. Calling .done() on promise means that the promise ends there. It cannot be chained further.

So, your code would look like this

exports.update = function (id, template) {
  if (!_isValid(template)) {
    return Q.reject(new Error('Invalid data', Error.INVALID_DATA));
  }

  return _update(id, template);
};

Now, the update function just returns a promise always. Its up to the callers to attach the success or failure handlers to it.

Upvotes: 3

Related Questions