Skip to content

Commit

Permalink
docs(schematypes): add some examples of getters and warning about usi…
Browse files Browse the repository at this point in the history
…ng `map()` getters with array paths

Fix #6637
  • Loading branch information
vkarpov15 committed Jul 29, 2018
1 parent 4071de4 commit f3af885
Showing 1 changed file with 63 additions and 1 deletion.
64 changes: 63 additions & 1 deletion docs/schematypes.jade
Expand Up @@ -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),
Expand Down Expand Up @@ -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.

<h3 id="getters"><a href="#getters">Getters</a></h3>

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}`);
```

<h3 id="customtypes"><a href="#customtypes">Creating Custom Types</a></h3>

Mongoose can also be extended with custom SchemaTypes. Search the
Expand Down

0 comments on commit f3af885

Please sign in to comment.