diff --git a/docs/documents.md b/docs/documents.md index 20764c6dbe..6aca081425 100644 --- a/docs/documents.md +++ b/docs/documents.md @@ -8,6 +8,7 @@ to documents as stored in MongoDB. Each document is an instance of its
  • Documents vs Models
  • Retrieving
  • Updating Using save()
  • +
  • Setting Nested Properties
  • Updating Using Queries
  • Validating
  • Overwriting
  • @@ -81,6 +82,54 @@ doc.name = 'foo'; await doc.save(); // Throws DocumentNotFoundError ``` +## Setting Nested Properties + +Mongoose documents have a `set()` function that you can use to safely set deeply nested properties. + +```javascript +const schema = new Schema({ + nested: { + subdoc: new Schema({ + name: String + }) + } +}); +const TestModel = mongoose.model('Test', schema); + +const doc = new TestModel(); +doc.set('nested.subdoc.name', 'John Smith'); +doc.nested.subdoc.name; // 'John Smith' +``` + +Mongoose documents also have a `get()` function that lets you safely read deeply nested properties. `get()` lets you avoid having to explicitly check for nullish values, similar to JavaScript's [optional chaining operator `?.`](https://masteringjs.io/tutorials/fundamentals/optional-chaining-array). + +```javascript +const doc2 = new TestModel(); + +doc2.get('nested.subdoc.name'); // undefined +doc2.nested?.subdoc?.name; // undefined + +doc2.set('nested.subdoc.name', 'Will Smith'); +doc2.get('nested.subdoc.name'); // 'Will Smith' +``` + +You can use optional chaining `?.` and nullish coalescing `??` with Mongoose documents. +However, be careful when using [nullish coalescing assignments `??=`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_assignment) to create nested paths with Mongoose documents. + +```javascript +// The following works fine +const doc3 = new TestModel(); +doc3.nested.subdoc ??= {}; +doc3.nested.subdoc.name = 'John Smythe'; + +// The following does **NOT** work. +// Do not use the following pattern with Mongoose documents. +const doc4 = new TestModel(); +(doc4.nested.subdoc ??= {}).name = 'Charlie Smith'; +doc.nested.subdoc; // Empty object +doc.nested.subdoc.name; // undefined. +``` + ## Updating Using Queries {#updating-using-queries} The [`save()`](api/model.html#model_Model-save) function is generally the right diff --git a/package.json b/package.json index c3645b8b55..cb5c6a4c4b 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "lint": "eslint .", "lint-js": "eslint . --ext .js --ext .cjs", "lint-ts": "eslint . --ext .ts", - "lint-md": "markdownlint-cli2 \"**/*.md\"", + "lint-md": "markdownlint-cli2 \"**/*.md\" \"#node_modules\" \"#benchmarks\"", "build-browser": "(rm ./dist/* || true) && node ./scripts/build-browser.js", "prepublishOnly": "npm run build-browser", "release": "git pull && git push origin master --tags && npm publish",