123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /*!
- * Module dependencies.
- */
- 'use strict';
- const EventEmitter = require('events').EventEmitter;
- const Subdocument = require('./subdocument');
- const utils = require('../utils');
- const documentArrayParent = require('../helpers/symbols').documentArrayParent;
- /*!
- * A constructor.
- *
- * @param {Object} obj js object returned from the db
- * @param {MongooseDocumentArray} parentArr the parent array of this document
- * @param {Boolean} skipId
- * @inherits Document
- * @api private
- */
- function ArraySubdocument(obj, parentArr, skipId, fields, index) {
- if (utils.isMongooseDocumentArray(parentArr)) {
- this.__parentArray = parentArr;
- this[documentArrayParent] = parentArr.$parent();
- } else {
- this.__parentArray = undefined;
- this[documentArrayParent] = undefined;
- }
- this.$setIndex(index);
- this.$__parent = this[documentArrayParent];
- Subdocument.call(this, obj, fields, this[documentArrayParent], skipId, { isNew: true });
- }
- /*!
- * Inherit from Subdocument
- */
- ArraySubdocument.prototype = Object.create(Subdocument.prototype);
- ArraySubdocument.prototype.constructor = ArraySubdocument;
- Object.defineProperty(ArraySubdocument.prototype, '$isSingleNested', {
- configurable: false,
- writable: false,
- value: false
- });
- Object.defineProperty(ArraySubdocument.prototype, '$isDocumentArrayElement', {
- configurable: false,
- writable: false,
- value: true
- });
- for (const i in EventEmitter.prototype) {
- ArraySubdocument[i] = EventEmitter.prototype[i];
- }
- /*!
- * ignore
- */
- ArraySubdocument.prototype.$setIndex = function(index) {
- this.__index = index;
- if (this.$__ != null && this.$__.validationError != null) {
- const keys = Object.keys(this.$__.validationError.errors);
- for (const key of keys) {
- this.invalidate(key, this.$__.validationError.errors[key]);
- }
- }
- };
- /*!
- * ignore
- */
- ArraySubdocument.prototype.populate = function() {
- throw new Error('Mongoose does not support calling populate() on nested ' +
- 'docs. Instead of `doc.arr[0].populate("path")`, use ' +
- '`doc.populate("arr.0.path")`');
- };
- /*!
- * ignore
- */
- ArraySubdocument.prototype.$__removeFromParent = function() {
- const _id = this._doc._id;
- if (!_id) {
- throw new Error('For your own good, Mongoose does not know ' +
- 'how to remove an ArraySubdocument that has no _id');
- }
- this.__parentArray.pull({ _id: _id });
- };
- /**
- * Returns the full path to this document. If optional `path` is passed, it is appended to the full path.
- *
- * @param {String} [path]
- * @param {Boolean} [skipIndex] Skip adding the array index. For example `arr.foo` instead of `arr.0.foo`.
- * @return {String}
- * @api private
- * @method $__fullPath
- * @memberOf ArraySubdocument
- * @instance
- */
- ArraySubdocument.prototype.$__fullPath = function(path, skipIndex) {
- if (this.__index == null) {
- return null;
- }
- if (!this.$__.fullPath) {
- this.ownerDocument();
- }
- if (skipIndex) {
- return path ?
- this.$__.fullPath + '.' + path :
- this.$__.fullPath;
- }
- return path ?
- this.$__.fullPath + '.' + this.__index + '.' + path :
- this.$__.fullPath + '.' + this.__index;
- };
- /*!
- * Given a path relative to this document, return the path relative
- * to the top-level document.
- */
- ArraySubdocument.prototype.$__pathRelativeToParent = function(path, skipIndex) {
- if (this.__index == null) {
- return null;
- }
- if (skipIndex) {
- return path == null ? this.__parentArray.$path() : this.__parentArray.$path() + '.' + path;
- }
- if (path == null) {
- return this.__parentArray.$path() + '.' + this.__index;
- }
- return this.__parentArray.$path() + '.' + this.__index + '.' + path;
- };
- /*!
- * Returns this sub-documents parent document.
- */
- ArraySubdocument.prototype.$parent = function() {
- return this[documentArrayParent];
- };
- /**
- * Returns this subdocument's parent array.
- *
- * #### Example:
- *
- * const Test = mongoose.model('Test', new Schema({
- * docArr: [{ name: String }]
- * }));
- * const doc = new Test({ docArr: [{ name: 'test subdoc' }] });
- *
- * doc.docArr[0].parentArray() === doc.docArr; // true
- *
- * @api public
- * @method parentArray
- * @returns DocumentArray
- */
- ArraySubdocument.prototype.parentArray = function() {
- return this.__parentArray;
- };
- /*!
- * Module exports.
- */
- module.exports = ArraySubdocument;
|