2

Using the mysql2/promise library, one of my objects partly consists of unresolved promises from previous SELECT statements.

When inserting, I get an incorrect integer value error message because the promises have not been resolved. What would be an elegant way to resolve the contained promises?

let insertObj = {
  author: this.authorId // unresolved promise #1
  recipient: this.recipientId // unresolved promise #2
  // ... more promises here
  message: this.messageBody
}

let conn = this.pool.getConnection();
return conn.then((conn) => {
  const res = conn.query("INSERT INTO posts SET ?", [insertObj]);
  conn.release();
  return res
});
wundervoll
  • 372
  • 1
  • 4
  • 15

1 Answers1

3

Use async/await:

async function f() {
    // Prefix all promises with await
    let insertObj = {
        author: await this.authorId,
        recipient: await this.recipientId,
        // ... more promises here
        message: await this.messageBody
    }

    let conn = this.pool.getConnection();
    return conn.then((conn) => {
        const res = conn.query("INSERT INTO posts SET ?", [insertObj]);
        conn.release();
        return res;
    });
}

Without async/await you could do this:

let insertObj = {
    author: this.authorId,
    recipient: this.recipientId,
    // ... more promises here
    message: this.messageBody
};
// Replace promises by their promised values as soon as they resolve:
Object.entries(insertObj).forEach( ([key, value]) => {
    if (typeof Object(value).then === 'function') // it is a "thenable"
        value.then ( response => insertObj[key] = response );
});
// Wait for all of them to resolve
Promise.all(Object.values(insertObj)).then( _ => {
    let conn = this.pool.getConnection();
    return conn.then((conn) => {
        const res = conn.query("INSERT INTO posts SET ?", [insertObj]);
        conn.release();
        return res;
    });
});
trincot
  • 317,000
  • 35
  • 244
  • 286
  • Short and elegant. Out of curiosity, how would I go about using regular promises? – wundervoll Aug 31 '17 at 22:58
  • What do you mean with regular promises? Is `this.authorId` not a regular promise? Or do you mean: "how can I do this without `async/await`, but with `then`?" – trincot Aug 31 '17 at 23:01
  • Yes, "how can I do this without async/await, but with then". I'm trying to understand what async/await are doing under the hood. – wundervoll Aug 31 '17 at 23:04
  • I tried author: new Promise((resolve, reject) => { this.authorId.then(r => { resolve(r)}) }) – wundervoll Aug 31 '17 at 23:05
  • No, that is a [promise constructor anti pattern](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) and does not help you further. I added a section to my answer: the key is `Promise.all`. – trincot Aug 31 '17 at 23:13