question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Schema.options.toObject.transform runs for every findOne query

See original GitHub issue

I am running “mongoose@6.0.9” and Node@14.17.6

Do you want to request a feature or report a bug?

I believe it is a bug given that this behaviour wasn’t present in 5.11.11

What is the current behavior?

When creating schema, I am using the toObject.transform options to strip fields like __v before presenting to users. I have noticed that whenever I set a toObject.transform function, it runs in all findOne queries

If the current behavior is a bug, please provide the steps to reproduce.

My code:

const schema = new mongoose.Schema({
  name: String,
  place: String
});

 if (!schema.options.toObject) schema.options.toObject = {};
schema.options.toObject.transform = function (doc, ret, options) {
     console.log('ret:', ret)
     delete ret.__v;
     delete ret.place;
     return ret;
 }

const model = mongoose.model("Model", schema);

async function findDocument() {
  await model.create({name: "Abel", place:"Istanbul"})
  const test= await model.findOne({name: "Abel"});
  
  console.log(test) // returns  object with _id and name. I need to prevent transform from running
}
With the transform function commented out, findOne query returns a Mongo document complete with fields

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
deistermatheuscommented, Oct 13, 2021

Update

I found out that console.log(test.place) still returns Istanbul, but console.log(test) returns an object without the place field. Any ideas why it is so?

Your transform does not apply to the underlying document, only to method calls targeting .toObject() or .toJSON(). Logging the top-level object applies the transform, but logging a property does not.

It is likely that logging a document calls toObject under the hood, but I haven’t checked the source code to point out exactly where.

   const test= await model.findOne({name: "Abel"}) // will have all fields and be an instance of mongoose.document
   const test= await model.findOne({name: "Abel"}).toObject() // will be a plain javascript object and will remove fields according to transform
0reactions
vkarpov15commented, Nov 17, 2021

@deistermatheus is right, console.log(test) calls the transform implicitly, here’s the relevant code in Mongoose. console.log() calls require('util').inspect(), which looks for the inspect() function. So this is expected behavior. transform is not called on findOne().

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mongoose v6.8.2: API docs
SchemaTypeOptions (). The constructor used for schematype options ... An array containing all connections associated with this Mongoose instance.
Read more >
Mongoose toObject and toJSON transform behavior with sub ...
Mongoose supports two Schema options to transform Objects after querying MongoDb: toObject and toJSON . In general you can access the returned ...
Read more >
How to protect the password field in Mongoose/MongoDB so it ...
JohnnyHKs answer using Schema options is probably the way to go here. ... findOne() // This should return an object excluding the password...
Read more >
An 80/20 Guide to Mongoose Plugins - The Code Barbarian
The last plugin use case you'll see in this article is tweaking schema options. This use case is primary useful for defining transform...
Read more >
Mongoose API v4.4.14
Equivalent to calling .plugin(fn) on each Schema you create. ... Mongoose#Query() ... transform : optional function which accepts a mongoose document.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found