Ethan Kent
Ethan Kent

Reputation: 541

ES6: How to return promise from inside then block

I am hashing a password with a function that returns a promise. I am trying to use the result with node-sqlite3, which has a db.run() method that accepts a SQL command, an array of parameters, and an optional callback. I tried something like the following:

var maybeError = hashPassword("foo")
  .then(function(hashed) {
    return new Promise(function(resolve, reject) { 
      db.run(
        "insert into blah hashed value ?",
        [hashed], 
        function(err) {
          if(err) reject(err); else resolve();
        }
      );
    });
  })
  .catch(//something else);

This idea works when not wrapped in the .then() block of the hashPassword() function. I want to export the maybeError Promise to a separate server.js file, which will use it to generate a HTTP status codes, etc.

Edit:

The comments correctly identify an error in the orignal Plunk that was an artifact of adapting the code to highlight the problem I was having.

Having corrected that error, I think there is still an error as shown in this updated Plunk.

// Simulate a database a la node-sqlite3
var fakeDb = function(sql, params, cb) {
  setTimeout(cb("Error"), 500);
};

// Test that the fakeDB() function works by itself
var noPromise = function(sql, params) {
  fakeDb(sql, params, function(e) {
    document.write(e);
  });
};

noPromise("foo", "bar");

// Wrap fakeDB() callback in single promise, that works
var singlePromise = function(sql, params) {
  return new Promise(function(resolve, reject) {
    fakeDb(sql, params, function(e) {
      if (e) {
        reject(e);
      } else {
        resolve();
      }
    });
  });
};

singlePromise("foo", "bar")
  .catch(function(e) {
    document.write(e);
  });


// Simulate a password hashing function that returns a promise
var hashPassword = function() {
  return new Promise(function(resolve, reject) {
    resolve();
  });
};

// Verify that the fake password hashing function works
hashPassword()
  .then(document.write("foo"));

/* Now attempt to return a promise from the fakeDB function,
 * but this time wrap that inside the then() block of hashPassword.
 * This doesn't work.
 */
var nestedPromise = hashPassword()
  .then(function(sql, params) {
    return new Promise(function(resolve, reject) {
      fakeDb(sql, params, function(e) {
        if (e) {
          reject(e);
        } else {
          resolve();
        }
      });
    });
  });

nestedPromise("foo", "bar") // <== This was the problem: should not have arguments.
  .catch(function(e) {
    document.write(e);
  })
  .then(function(x) {
    document.write(x);
  });

This writes ErrorfooError but not ErrorfooErrorError to the document. That return in the nestedPromise() function does not appear to be working.

Thanks!

Upvotes: 0

Views: 839

Answers (2)

Ethan Kent
Ethan Kent

Reputation: 541

The problem appears to be that I was calling nestedPromise with arguments. @Bergi edited my Plunk to remove the arguments. So it is possible to return a promise in the way I was attempting, as long as you don't screw up the function call like a moron.

Upvotes: 0

Bergi
Bergi

Reputation: 664920

Error is not appearing from the call to nestedPromise.

That's because nestedPromise is a Promise (like oldPromise), not a function (unlike noPromise or singlePromise). You cannot call it. You can even see that in the console:

Uncaught TypeError: nestedPromise is not a function

Upvotes: 1

Related Questions