From c81b7a8b32c0bfeb883ecf38aacc3943b00aba0b Mon Sep 17 00:00:00 2001 From: Jack Linhart Date: Thu, 13 Apr 2023 14:32:31 -0500 Subject: [PATCH 1/2] Remove direction to include virutals in toObject Passing {virtuals: true} to toObject does not have the same effect as toJSON{ vrituals: true} Tested on Ubuntu 22.04 and Windows 10 using version "^6.9.2" Can be replicated with the following model file: const postSchema = new Schema( { text: String, username: String, comments: [{ type: Schema.Types.ObjectId, ref: 'comment' }], }, { // replace with toJSON to revert to correct behavior toObject: { virtuals: true, }, } ); // Create a virtual property `commentCount` that gets the amount of comments per post postSchema.virtual('commentCount').get(function () { return this.comments.length; }); // Initialize our Post model const Post = model('post', postSchema); Please correct if I'm using this code erroneously --- docs/guide.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/guide.md b/docs/guide.md index 26685378307..d43d014f179 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -374,8 +374,7 @@ console.log(axl.fullName); // Axl Rose If you use `toJSON()` or `toObject()` mongoose will *not* include virtuals by default. This includes the output of calling [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) on a Mongoose document, because [`JSON.stringify()` calls `toJSON()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description). -Pass `{ virtuals: true }` to either -[`toObject()`](api/document.html#document_Document-toObject) or [`toJSON()`](api/document.html#document_Document-toJSON). +Pass `{ virtuals: true }` to [`toJSON()`](api/document.html#document_Document-toJSON). You can also add a custom setter to your virtual that will let you set both first name and last name via the `fullName` virtual. From 4f13e9953d04cb81f05bcdb9f4bf612e4e51b4e0 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 15 May 2023 21:28:57 -0400 Subject: [PATCH 2/2] Update guide.md --- docs/guide.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/docs/guide.md b/docs/guide.md index d43d014f179..370dbeb785d 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -371,10 +371,34 @@ Now, mongoose will call your getter function every time you access the console.log(axl.fullName); // Axl Rose ``` -If you use `toJSON()` or `toObject()` mongoose will *not* include virtuals -by default. This includes the output of calling [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) -on a Mongoose document, because [`JSON.stringify()` calls `toJSON()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description). -Pass `{ virtuals: true }` to [`toJSON()`](api/document.html#document_Document-toJSON). +If you use `toJSON()` or `toObject()` Mongoose will *not* include virtuals by default. +Pass `{ virtuals: true }` to [`toJSON()`](api/document.html#document_Document-toJSON) or `toObject()` to include virtuals. + +```javascript +// Convert `doc` to a POJO, with virtuals attached +doc.toObject({ virtuals: true }); + +// Equivalent: +doc.toJSON({ virtuals: true }); +``` + +The above caveat for `toJSON()` also includes the output of calling [`JSON.stringify()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) on a Mongoose document, because [`JSON.stringify()` calls `toJSON()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description). +To include virtuals in `JSON.stringify()` output, you can either call `toObject({ virtuals: true })` on the document before calling `JSON.stringify()`, or set the `toJSON: { virtuals: true }` option on your schema. + +```javascript +// Explicitly add virtuals to `JSON.stringify()` output +JSON.stringify(doc.toObject({ virtuals: true })); + +// Or, to automatically attach virtuals to `JSON.stringify()` output: +const personSchema = new Schema({ + name: { + first: String, + last: String + } +}, { + toJSON: { virtuals: true } // <-- include virtuals in `JSON.stringify()` +}); +``` You can also add a custom setter to your virtual that will let you set both first name and last name via the `fullName` virtual.