Naltroc
Naltroc

Reputation: 1007

Updating object property with value of Promise

I using Express with Node to interact with a MySQL database. The create method of my Card object will save the data to the database and should update the object's id to be the insertId returned from the query.

class Card {
    constructor(d) {
        this.id = d.id || 0;
        this.playerId = d.playerId;
        this.drawn = false;
        this.title = d.title
        this.qty = d.qty;
        this.hint = d.hint;
        this.type = d.type;
        this.descr = d.descr;
        this.pair = d.pair
        this.data = d;
    }

    create(conn) {
        return new Promise( (resolve, reject) => {
            var query = "INSERT INTO cards SET ? ";

            conn.query(query, this.data, function(err, result) {
                if (err) throw err;
                (typeof result.insertId === 'number')
                    ? resolve(result.insertId)
                    : reject("Failed to insert a new Card.");
                resolve(result.insertId);
            })

        }).then( (id) => {
            this.id = id;
            console.log("Your insert id is");
            console.log(this.id) // GREAT! It prints the correct id
            return this; // Set the value of the promise to this Card instance
        })
    }

} 

After creating a card, it should print the json representation of the card.

router.post('/create-card', function(req, res) {
    var data = req.body;
    var card = new Card(data);
    card = card.create(db.connection);
    res.json(card);
})

But the id of the returned object is always the default value (0).

I have played with a few different ways of trying to capture the id, set the object's id property with the new value, and persist that value to the object. However, it always seems to be a more locally scoped version of the card that gets updated, not the original card (which is printed to the page).

When using Promises, what is the proper place to assign object data and return that instance of the object?

Upvotes: 1

Views: 2202

Answers (2)

Yossi
Yossi

Reputation: 445

You are doing an async operation in create method but dont use it properly. You have to do one of two things:

  1. Return promise from create, then wait for it to fulfilled with 'then' in your post route.
  2. Use await and wait for the promise to be resolved.

In your code for now you are running in your router synchronize code while your create operation is async...

Upvotes: 0

trincot
trincot

Reputation: 350760

You're calling res.json too soon. You need to await the promise's resolution:

card.create(db.connection).then( _ => res.json(card));

Upvotes: 2

Related Questions