diff --git a/docs/schematypes.jade b/docs/schematypes.jade index 47bc6e8b615..f5d67e09709 100644 --- a/docs/schematypes.jade +++ b/docs/schematypes.jade @@ -10,7 +10,7 @@ block content SchemaTypes handle definition of path [defaults](./api.html#schematype_SchemaType-default), [validation](./api.html#schematype_SchemaType-validate), - [getters](./api.html#schematype_SchemaType-get), + [getters](#getters), [setters](./api.html#schematype_SchemaType-set), [field selection defaults](./api.html#schematype_SchemaType-select) for [queries](./api.html#query-js), @@ -375,6 +375,68 @@ block content Keys in a BSON object are ordered, so this means the [insertion order](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Description) property of maps is maintained. +

Getters

+ + Getters are like virtuals for paths defined in your schema. For example, + let's say you wanted to store user profile pictures as relative paths and + then add the hostname in your application. Below is how you would structure + your `userSchema`: + + ```javascript + const root = 'https://s3.amazonaws.com/mybucket'; + + const userSchema = new Schema({ + name: String, + picture: { + type: String, + get: v => `${root}${v}` + } + }); + + const User = mongoose.model('User', userSchema); + + const doc = new User({ name: 'Val', picture: '/123.png' }); + doc.picture; // 'https://s3.amazonaws.com/mybucket/123.png' + doc.toObject({ getters: false }).picture; // '123.png' + ``` + + Generally, you only use getters on primitive paths as opposed to arrays + or subdocuments. Because getters override what accessing a Mongoose path returns, + declaring a getter on an object may remove Mongoose change tracking for + that path. + + ```javascript + const schema = new Schema({ + arr: [{ url: String }] + }); + + const root = 'https://s3.amazonaws.com/mybucket'; + + // Bad, don't do this! + schema.path('arr').get(v => { + return v.map(el => Object.assign(el, { url: root + el.url })); + }); + + // Later + doc.arr.push({ key: String }); + doc.arr[0]; // 'undefined' because every `doc.arr` creates a new array! + ``` + + Instead of declaring a getter on the array as shown above, you should + declare a getter on the `url` string as shown below. If you need to declare + a getter on a nested document or array, be very careful! + + ```javascript + const schema = new Schema({ + arr: [{ url: String }] + }); + + const root = 'https://s3.amazonaws.com/mybucket'; + + // Good, do this instead of declaring a getter on `arr` + schema.path('arr.0.url').get(v => `${root}${v}`); + ``` +

Creating Custom Types

Mongoose can also be extended with custom SchemaTypes. Search the