1

while development of an API, I often need to set extra properties in the result of mongoDb query results. But I can't do it in a good way. For example

Model

const Cat = mongoose.model('Cat', { name: String,age:Number });

Query

Cat.findOne({age:2})  .then(
    cat=>{
        cat.breed="puppy";    
        console.log(cat)
    } )

here after I get the result from mongoDb I want to set the property of breed to the result , but I can't do it because the property is not defined in the Schema

So to set an extra property I use a hack

cat = JSON.parse(JSON.stringify(cat));
cat.favFood = "Milk"

I don't think its a good way to code. please give a better way of setting property and explain how the hack is working.

Ankit Halder
  • 167
  • 1
  • 4
  • 16

2 Answers2

4

Mongoose can actually do the conversion toObject for you with the .lean() option. This is preferred over manual conversion after the query (as willis mentioned) because it optimizes the mongoose query by skipping all the conversion of the raw Mongo document coming from the DB to the Mongoose object, leaving the document as a plain Javascript object. So your query will look something similar to this:

Cat.findOne({age:2}).lean().then(
    cat=>{
        cat.breed="puppy";    
        console.log(cat)
    }
)

The result will be the same except that this will skip the Mongoose document-to-object conversion middleware. However, note that when you use .lean() you lose all the Mongoose document class methods like .save() or .remove(), so if you need to use any of those after the query, you will need to follow willis answer.

3

Rather than using JSON.parse and JSON.stringify, you can call toObject to convert cat into a regular javascript object.

Mongoose objects have methods like save and set on them that allow you to easily modify and update the corresponding document in the database. Because of that, they try to disallow adding non-schema properties.

Alternatively, if you are trying to save these values you to the database, you may wish to look into the strict option (which is true by default).

klhr
  • 3,300
  • 1
  • 11
  • 25