How to Convert Entity to Plain Object in Sequelize.js

Updated: December 29, 2023 By: Guest Contributor Post a comment

Overview

Sequelize is one of the most popular ORMs for relational databases with Node.js. It abstracts database access and enables developers to interact with various SQL databases with ease. Sometimes, while working with Sequelize, we need to convert entities to plain objects to decouple our database layer from our application logic, or for purposes like JSON serialization. This process is known as ‘dehydrating’ an instance. In this tutorial, we will explore several methods to convert a Sequelize entity to a plain object, starting with the basics and moving into more advanced territory.

Basic Conversion Using toJSON

The simplest way to convert a Sequelize instance to a plain object is by using the toJSON method which is automatically made available on every Sequelize model instance.

const user = await User.findByPk(1);
const plainUser = user.toJSON();
console.log(plainUser);

This will give you a JS object with only the data values of the Sequelize instance.

Using get with the { plain: true } Option

The get method is a bit more versatile. You can fetch just the data you need by passing attributes, and turn the model instance into a plain object by setting the plain option to true.

const user = await User.findByPk(1);
const plainUser = user.get({ plain: true });
console.log(plainUser);

Serialization with Custom Methods

Sometimes, you want to control the serialization process. This can be done by adding a custom method to your model.

User.prototype.toSimpleJSON = function () {
  const values = this.get();
  delete values.password; // Excluding password from the user object
  return values;
};

const user = await User.findByPk(1);
const plainUser = user.toSimpleJSON();
console.log(plainUser);

Advanced: Leveraging Projection in Queries

Projection is the ability to choose which attributes you want to retrieve from the database. Sequelize allows you to specify these attributes in your query, which means Sequelize only fetches the specified fields, resulting in a lighter instance. This can automatically act as a conversion to a plain object when combined with the get method.

const user = await User.findByPk(1, {
  attributes: ['id', 'name', 'email'], // Only fetch these attributes
});
const plainUser = user.get({ plain: true });
console.log(plainUser);

Handling Associations and Lazy-Loading

Working with associated models can add complexity when converting to plain objects. When using lazy loading, watch out for operations that might inadvertently trigger loading of associated models.

const user = await User.findByPk(1);
const plainUser = user.get({ plain: true });

// Assume 'profile' is a lazily-loaded association
// Accessing it will trigger a database call
const userProfile = await user.getProfile();
plainUser.profile = userProfile.get({ plain: true });

console.log(plainUser);

Utilizing Sequelize Hooks for Automatic Conversion

Sequelize hooks provide a powerful way to automate processes like entity conversion. For instance, you can use the afterFind hook to convert every instance that is retrieved from the database.

User.addHook('afterFind', (findResult) => {
  if (!Array.isArray(findResult)) findResult = [findResult];
  for (const instance of findResult) {
    if (instance instanceof User) {
      instance.dataValues = instance.get({ plain: true });
    }
  }
});

// Any find operation now returns a plain object
const user = await User.findByPk(1);
console.log(user.dataValues);

Conclusion

In this tutorial, we have covered multiple ways to convert a Sequelize entity to a plain object, from simple one-liners to more advanced techniques. Understanding these methods will help you handle data transformation effectively in your Node.js applications using Sequelize. Remember to consider performance implications and choose the right approach for your specific situation.