Mongoose: Documentation: clarify the difference between toObject() and toJSON()

Created on 13 May 2014  路  6Comments  路  Source: Automattic/mongoose

What is the difference between these two? It's not immediately apparent which I should be targeting when I use a transform. Up until now I have just blindly added the same transform on both.

My use case: I want to be able to modify the json that is sent to the front end (through express), but I don't want this modified data to be persisted to the database whenever a save() is called.

help

Most helpful comment

To all y'all finding this in 2019...

JSON.stringify checks objects passed to it for a function called toJSON. If it exists it uses that function to determine the object that should be stringified. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior

If you are using express, when calling res.send(object) and the client accepts JSON it will JSON.stringify the object passed into send. This means when you pass a mongoose model directly into res.send(model) it will send the toJSON format. If you just need to get an object representation of your model then I would use toObject.

If you ever have a use case where you want your models turned into objects in two different ways, then it makes sense to have both. If you want to be able to easily res.send(model) you need toJSON, and if you ever want to toObject that produces a result other than toJSON you need that to run with it's own options.

toJSON seems to essentially just exist for compatibility with utilities that already call toJSON such as JSON.stringify.

All 6 comments

Re: your use case, it sounds like you can just use virtuals, no?

As for the difference between toJSON and toObject, they are fairly interchangeable. toJSON is mostly a thin wrapper around toObject.

Virtuals look good, thanks for the link.

I guess I still don't really know if/when I should use toObject or toJson. If they are fairly interchangeable, why do they both exist?

But maybe I don't need to use either, now.

I'm actually not entirely sure why both exist :) Personally, I would just use toObject, but I'm going to investigate whether or not it makes sense to have both.

To all y'all finding this in 2019...

JSON.stringify checks objects passed to it for a function called toJSON. If it exists it uses that function to determine the object that should be stringified. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior

If you are using express, when calling res.send(object) and the client accepts JSON it will JSON.stringify the object passed into send. This means when you pass a mongoose model directly into res.send(model) it will send the toJSON format. If you just need to get an object representation of your model then I would use toObject.

If you ever have a use case where you want your models turned into objects in two different ways, then it makes sense to have both. If you want to be able to easily res.send(model) you need toJSON, and if you ever want to toObject that produces a result other than toJSON you need that to run with it's own options.

toJSON seems to essentially just exist for compatibility with utilities that already call toJSON such as JSON.stringify.

@pritchardtw thanks for the detailed write up :+1:

A difference between toJSON and toObject I've found is that properties on the schema defined as a map seem to be set to an empty object when calling toObject.

I'm not sure if this behaviour is intended or not but makes toJSON much more useful in the case the record contains a map.

Was this page helpful?
0 / 5 - 0 ratings