Sequelize hooks explained with code examples

Posted on Feb 15, 2022

Learn how Sequelize hooks can be useful for manipulating your database

Sequelize hooks are lifecycle events that get executed during a specific period of time.

These hooks are JavaScript functions that run before or after an operation has been completed by Sequelize.

Let’s see an easy example that demonstrates one of the hooks in action.

Suppose you have an SQL table named Users with the following definitions:

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int          | NO   | PRI | NULL    | auto_increment |
| firstName | varchar(255) | YES  |     | NULL    |                |
| email     | varchar(255) | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

Each time a new user row is saved on the table, you want to send an email notification to the registered email address.

You can do so by adding an afterCreate hook to the model that represents the Users table above.

Here’s one example of adding a hook to your model:

// 1. Define the model
const User = sequelize.define(
  "User",
  {
    firstName: Sequelize.STRING,
    email: Sequelize.STRING,
  },
  { timestamps: false }
);

// 2. Add the hook. This one is afterCreate hook
User.afterCreate(async (user, options) => {
  console.log("New User created:");
  console.log(user.firstName);
  console.log(user.email);
});

Now when you call the create() method from the model, the afterCreate hook will be executed after the method call.

Sequelize also passes the new row data to the hook function as the first argument.

Let’s insert a new row as shown below:

await User.create({
  firstName: "Nathan",
  email: "nathan@mail.com",
});

You’ll see the following output in the console:

New User created:
Nathan
nathan@mail.com

There are many hooks provided by Sequelize that get executed at specific moments.

The full list of Sequelize hooks can be found in the hooks.js file of the library.

The order of execution of the most popular hooks are roughly as follows:

beforeConnect(callback)
afterConnect(callback)

beforeInit(config, options) // before Sequelize() connection call
afterInit(sequelize) // the created sequelize instance
beforeDefine(attributes, options) // before model definition
afterDefine(factory)

beforeValidate(instance, options)

// [validation proceeds]

afterValidate(instance, options)
validationFailed(instance, options, error)

// before query method calls
beforeCreate(instance, options)
beforeDestroy(instance, options)
beforeUpdate(instance, options)
beforeSave(instance, options)
beforeUpsert(values, options)

// [query method calls proceed]

afterCreate(instance, options)
afterDestroy(instance, options)
afterUpdate(instance, options)
afterSave(instance, options)
afterUpsert(created, options)

beforeDisconnect(callback)
afterDisconnect(callback)

Note that you can add hooks to a model in three different ways:

  • Directly define the function property to the model object
  • As an option to the model during the define() call
  • Using the addHook() function

You can define the function on the model object itself as shown above:

User.afterCreate()

Or you can add it as one of the option parameters for the model itself inside the define() call.

The hooks must be defined under the hooks object as shown below:

const User = sequelize.define(
  "User",
  {
    firstName: Sequelize.STRING,
    email: Sequelize.STRING,
  },
  {
    timestamps: false,
    hooks: {
      afterCreate: (user, options) => {
        console.log("New User created:");
        console.log(user.firstName);
        console.log(user.email);
      },
    },
  }
);

Or you can also call the addHook() function from the model:

User.addHook('afterCreate', (user, options) => {
  console.log("New User created:");
  // ...
});

You can also define a global hook for all models to call during a specific event.

A global hook is defined in the new Sequelize() function call as shown below:

const sequelize = new Sequelize( /* credentials */, {
  host: "localhost",
  dialect: "mysql",
  define: {
    hooks: {
      beforeCreate() {
        // Do stuff
      }
    }
  }
});

Hooks defined in the Sequelize() call will be executed for all models created using the returned sequelize instance.

You can override global hooks from the individual models when you want to, but they will be called when you don’t have any local model hooks.

And that’s how hooks work in Sequelize. For more information, you can view the Sequelize hooks documentation.

Great work on learning about Sequelize hooks! 👍

Level up your programming skills

I'm sending out an occasional email with the latest programming tutorials. Drop your email in the box below and I'll send new stuff straight into your inbox!

No spam. Unsubscribe anytime.