Search code examples
javascriptnode.jspromisesequelize.jses6-promise

Sequelize Update Returning Before and After Results


I'm trying to create an Update API route using Sequelize that will:

  1. Capture the record before the update (beforeRec)
  2. Perform the update
  3. Capture the updated record (updatedRec)
  4. Return both the beforeRec and updatedRec

I'm having trouble with my promise chain, which is executing the before and after select queries before executing the update. I've tried several different ways of chaining and capturing results, but here's the latest code:

router.put('/:id', (req, res) => {
  const pk = req.params.id;

  const getBeforeRec = Master.findByPk(pk)
    .then(rec => {return rec})

  const updateRec = getBeforeRec
    .then(
      Master.update(
        req.body,
        { where: {id: pk} }
      )  
    )

  const getUpdatedRec = updateRec
    .then(
      Master.findByPk(pk)
        .then(rec => {return rec})
    );

  return Promise.all([getBeforeRec, updateRec, getUpdatedRec])
    .then( ([beforeRec, updateRes, afterRec]) => {
      return res.json({beforeRec, afterRec})
    })
    .catch(err => {
      return res.status(400).json({'error': err});
    });
});

Here's a sanitized example of how the results look:

{
    "beforeRec": {
        "id": 100,
        "updated_col_name": false,
    },
    "afterRec": {
        "id": 100,
        "updated_col_name": false,
    }
}

In the console, I can see that the update is executing last:

Executing (default): SELECT [id], [updated_col_name] FROM [master] WHERE [master].[id] = N'100';
Executing (default): SELECT [id], [updated_col_name] FROM [master] WHERE [master].[id] = N'100';
Executing (default): UPDATE [master] SET [updated_col_name]=1 WHERE [id] = N'106'

What's the best way to make the second select statement wait for the update?

Any help in clarifying how to chain promises while capturing results along the way will be greatly appreciated! Thanks.


Solution

  • You can do that with , previous method of the instance that returned by update query :

    Master.update( req.body , { where: {id: pk} }).then(master => {
        console.log(master.get());          // <---- Will give you latest values
        console.log(master.previous());     // <---- returns the previous values for all values which have changed
    })  
    

    For More Detail :

    http://docs.sequelizejs.com/class/lib/model.js~Model.html#instance-method-previous

    https://github.com/sequelize/sequelize/issues/1814