Michael Cranston

How Sequelize Serializes Objects

When retrieiving data from Sequelize, you don’t get a javascript object representing your data, you get a javascript object representing a model instance.

This confused me. So I began tracing how a Sequelize model instance becomes JSON for a front end to consume. Here are the steps:

1. Sequelize retrieves a record from the database and returns a javascript object (i.e. a model instance) representing that data.

const movie = await Movie.findById('1234');
console.log(movie);
// {
//   dataValues:{
//     name: 'Ladybird',
//     created_at: 2016-02-08T19:46:08.303Z
//   },
//   _changed: {},
//   _modelOptions: {},
//   _options: {}},
//   __eagerlyLoadedAssociations: [],
//   isNewRecord: false,
//   toJSON: function() {
//     // return JSON representation of instance
//   }
// }

2. ExpressJS sends the model instance back with res.send:

const movie = await Movie.findById('1234');
res.status(200).send(movie);

By calling .send, Express starts serialization:

  • The .send method calls JSON.stringify(instance) with Sequelize model instance (Reference)
  • JSON.stringify() then checks to see if the object being stringified has a function named toJSON. If it does, it will stringify the return value of that function. If not, it will stringify the plain object being passed. (Reference)
  • Since each Sequelize instance has a toJSON method, the final object being returned to the user is the result of that method (Reference)

This means if you ever want to add custom properties to your return value, you will need to add those values to a raw javascript object, not the instance itself:

const instance = await Movie.findById('1234');
instane.newProp = '1234'; // this does nothing
const movie = instance.get(); // {name: 'Ladybird'}
movie.extraProperty = '1234';
res.status(200).send(movie);
comments powered by Disqus