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:

  • if there is an error during the promise propagation - it should handle it,
  • or, if there wasn't an error - it should do some other things

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

Answers:

Answer

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.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.