This is my Mongoose schema:
const mongoose = require('mongoose');
const mongooseUniqueValidator = require('mongoose-unique-validator');
const mongooseTimestamp = require('mongoose-timestamp');
const Schema = mongoose.Schema;
const SectionSchema = new Schema({
name: {type: 'String', required: true},
system: {type: Schema.Types.ObjectId, required: true, ref: 'System'},
subsystem: {type: Schema.Types.ObjectId, required: true, ref: 'Subsystem'},
createdBy: {type: Schema.Types.ObjectId, required: true, ref: 'User'},
allowedUsers: [{
user: {type: Schema.Types.ObjectId},
actions: {type: 'String'},
_id: false
}],
}, {versionKey: 'versionKey'});
SectionSchema.plugin(mongooseTimestamp);
SectionSchema.plugin(mongooseUniqueValidator);
module.exports = mongoose.model('Section', SectionSchema);
the actions parameter save like this:
{"get":true,"post":true,"put":true,"delete":true}
I want to cast it to an object (in Moongoose find result), so I use getter:
const mongoose = require('mongoose');
const mongooseUniqueValidator = require('mongoose-unique-validator');
const mongooseTimestamp = require('mongoose-timestamp');
const Schema = mongoose.Schema;
const SectionSchema = new Schema({
name: {type: 'String', required: true},
system: {type: Schema.Types.ObjectId, required: true, ref: 'System'},
subsystem: {type: Schema.Types.ObjectId, required: true, ref: 'Subsystem'},
createdBy: {type: Schema.Types.ObjectId, required: true, ref: 'User'},
allowedUsers: [{
user: {type: Schema.Types.ObjectId},
actions: {type: 'String',get:toObject}, /* <------- */
_id: false
}],
}, {versionKey: 'versionKey'});
SectionSchema.plugin(mongooseTimestamp);
SectionSchema.plugin(mongooseUniqueValidator);
function toObject (v) { /* <------- */
return JSON.parse(v);
}
SectionSchema.set('toObject', { getters: true }); /* <------- */
SectionSchema.set('toJSON', { getters: true }); /* <------- */
module.exports = mongoose.model('Section', SectionSchema);
But I don't know why getter not working on object schema like allowedUsers.
The find request:
this.model.Section.find(filterParameters, {
_id: 0,
versionKey: 0
}).skip(offset).limit(limit).sort({createdAt: sort})
.populate('system', {_id: 0, name: 1})
.populate('subsystem', {_id: 0, name: 1})
.populate('createdBy', {_id: 0, username: 1})
.populate({
path: 'allowedUsers.user',
model: "User",
select: {username: 1, organization: 1, _id: 0},
populate: {
path: 'organization',
model: 'Organization',
select: {name: 1, _id: 0},
}
})
.exec((error, sections) => {
if (error) {
reject({
statusCode: "422",
message: error
});
} else if ((!sections || sections.length === 0)) {
reject({
statusCode: "404",
message: "No Result"
});
} else {
resolve({
data: sections,
filterParameters: filterParameters
});
}
});
Thanks for any idea...
Related
The field (viewed_posts) i want to populate in User Schema:
viewed_posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Viewed"
}
]
Viewed Schema :
var viewedSchema = new mongoose.Schema({
hitsByUser: {type: Number, default: 0},
viewsByUser: {type: Number, default: 0},
post: {
type: mongoose.Schema.Types.ObjectId,
ref: "Post"
}
});
Post Schema :
var mongoose = require('mongoose');
var passportLocalMongoose = require("passport-local-mongoose");
var uniqueValidator = require('mongoose-unique-validator');
var marked = require('marked');
var slugify = require('slugify');
// this is done for sanitizing html so that user cannot write a script in the input
const createDomPurify = require('dompurify')
const {JSDOM} = require('jsdom')
const dompurify = createDomPurify(new JSDOM().window)
var postSchema = new mongoose.Schema({
postNumber: Number,
title: String,
content: String,
subject: String, // currently we have 4 subjects so one out of 4 subjects will be stored here
likes: {type:Number,default:0},
// likes: {
// id:{
// type: mongoose.Schema.Types.ObjectId,
// ref: "User"
// }
// },
views: {type:Number,default:0},
actualViews: {type:Number,default:0},
shares: Number,
isReviewedByAdmin: {type: Boolean, default: false},
isReviewedByAuditor: {type: Boolean, default: false},
author: {
id:{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: {
type: String
}
},
publish_date: {
type: String,
default: Date.now
},
publishDay: String,
slug: {
type: String,
required: true,
},
sanitizedHtml: {
type: String,
required: true
},
imagename: String //2002-12-09
});
I wish to see whole structure printed , but i can only populate viewed_posts, how can i populate "post"
which is inside viewed Schema and see here:
User.findById(req.user._id).populate("viewed_posts").exec((err,ans)=>{
if(err) console.log(err)
else{
console.log("this is the answer ",ans)
}})
The output i get:
},
{
hitsByUser: 0,
viewsByUser: 0,
_id: 5f9e85aeec37700f54a4d029,
post: 5f9a93d38d7cf8544ce9cc21,
__v: 0
},
{
hitsByUser: 0,
viewsByUser: 0,
_id: 5f9e85d61841000478c85f8a,
post: 5f82773f1998150024d4c8fc,
__v: 0
},
But i expect this post to be expanded too, instead of just showing id , How can i achieve it. Any Help Would be appreciated.
Mongoose supports nested populating (see in the docs: https://mongoosejs.com/docs/populate.html#deep-populate).
Note that you have to specify your model name of post schema where I´ve put the "post-model-name" placeholder.
So you could try something like this:
User.findById(req.user._id)
.populate({
path: 'viewed_posts',
populate: {
path: 'post',
model: 'post-model-name'
}
})
.exec();
I am trying to create a chat with node.js, Express & MongoDB. I have two mongoose models: for chat room and message.
Room model:
const RoomSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
owner: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users',
required: true,
},
messages: {
type: [mongoose.Schema.Types.ObjectId],
ref: 'Messages',
required: true,
},
users: {
type: [mongoose.Schema.Types.ObjectId],
ref: 'Users',
required: true,
},
});
const Room = mongoose.model('Rooms', RoomSchema);
Message model:
const MessageSchema = new mongoose.Schema({
text: {
type: String,
required: true,
},
sendBy: {
type: String,
required: true
}
});
const Messages = mongoose.model('Messages', MessageSchema);
and a function for displaying all messages
prepareMessages: function (name, callback) {
rooms.findOne({
name: name,
}).populate('messages')
.exec(function (err, room) {
let result = '';
if (!room) {
console.log("Chat does not exist");
throw err;
}
else {
room.messages.forEach(function (item, i, arr) {
result += '<dt>' + item.sendBy + '</dt>';
result += '<dd>' + item.text + '</dd>';
});
}
callback(result)
});
},
Why do I get
TypeError: Cannot read property 'sendBy' of undefined?
I tried .populate('rooms.messages'), .populate({path: 'rooms.messages', model:'Messages') and another variants, but it still doesn't work. Help me, please!
In the Room Schema, you're defining the messages as an object with type of Array of ObjectId, while it should be an array of elements, each element is of type ObjectId, messages should be an array of ObjectIds, and users as well
const RoomSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
owner: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users',
required: true,
},
messages: [{ // note here messages is an array
type: mongoose.Schema.Types.ObjectId,
ref: 'Messages',
required: true,
}],
users: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Users',
required: true,
}],
});
const Room = mongoose.model('Rooms', RoomSchema);
hope it helps
sendBy should be of type ObjectId
const MessageSchema = new mongoose.Schema({
text: {
type: String,
required: true,
},
sendBy: {
type: mongoose.Schema.Types.ObjectId,
required: true
}
});
const Messages = mongoose.model('Messages', MessageSchema);
ref should be in lowercase.
ref: 'Users', should be changed to ref:'users'
Similarly at all other refs
I have 2 models, category and story.
Story contains reference id of the category.
In controller story, I have a function mystories which should fetch all the story records of particular user along with category information.
I am getting data from story collection but not from category collection.
The result which I receive is something like this:
category_id: "5d10978c8e0f5d5380fdb3e6"
created_at: "2019-06-25T10:02:47.637Z"
created_by: "5d1066fba920ef2ccfe68594"
image: "uploads/1561456967615_164.jpg"
published: "no"
status: "pending"
text: "<p><strong>Fashion</strong> is a popular aesthetic expression in a certain time and context, especially in clothing, footwear, lifestyle, accessories, makeup, hairstyle and body </p>"
title: "New fashion"
__v: 0
_id: "5d11f14757f8616041616217"
It should however return category collection information instead of
category id.
Category model:
const mongoose = require('mongoose');
const categorySchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: {
type: String,
required: true,
unique: true
},
status: {
type: String,
required: true,
enum: ['active','inactive','deleted']
},
created_at: { type: Date, default: Date.now },
created_by: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true},
});
module.exports = mongoose.model('Category', categorySchema);
Story model:
const mongoose = require('mongoose');
const storySchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: {
type: String,
required: true
},
text: {
type: String,
required: true
},
category_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Category',
required: true
},
image: {
type: String,
required: true
},
status: {
type: String,
required: true,
enum: ['pending','approved','deleted']
},
published: {
type: String,
required: true,
enum: ['yes','no']
},
created_at: { type: Date, default: Date.now },
created_by: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true},
});
module.exports = mongoose.model('Story', storySchema);
Controller code:
const mongoose = require('mongoose');
const Story = require('../models/story');
const Category = require('../models/category');
exports.mystories = async (req, res, next) => {
const user_id = req.userData.id;
const all_stories = await Story
.find({ created_by: user_id})
.populate('name','category')
.sort({ created_at: -1 })
.exec();
if(all_stories.length > 0) {
return res.status(200).json({
response: all_stories
});
}else {
return res.status(200).json({
response: []
});
}
};
exports.add_story = (req, res, next) => {
console.log(req.file);
const story = new Story({
_id: new mongoose.Types.ObjectId(),
title: req.body.story_title,
text: req.body.story_text,
category_id: req.body.story_category,
image: req.file.path,
status: 'pending',
published: 'no',
created_by: req.userData.id
});
story
.save()
.then(result => {
console.log(result);
res.status(200).json({
response: 'added_story'
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
})
});
};
populate takes the field name as it is given in story schema.
it should be :
.populate({path: 'category_id', select: 'name'})
I have this schema for users:
var mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
mongoose.Promise = global.Promise;
var userSchema = new mongoose.Schema ({
username: {type: String, required: true, unique: true},
password: {type: String},
role: {type: String, required: true},
confirmed: {type: Boolean, required: true, default: false},
active: {type: Boolean, required: true, default: true},
name: String,
created: {type: Date, default: Date.now},
admin: {type: Boolean, default: false, required: true}
});
userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", userSchema);
And another schema for companies, where clients refer to an array of users:
var mongoose = require("mongoose");
mongoose.Promise = global.Promise;
var companySchema = new mongoose.Schema ({
name: {type: String, required: true, unique: true},
created: {type: Date, default: Date.now},
active: {type: Boolean, required: true, default: true},
staff: [{
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}],
clients: [{
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}]
});
module.exports = mongoose.model("Company", companySchema);
I have the below code in my route, but the user information is not being populated into the company object, what am I doing wrong?
// EDIT route
router.get("/:company_id/edit", middleware.checkCompanyOwnership, function(req, res) {
Company.findOne({_id: req.params.company_id}).populate({path: 'clients'}).exec(function(err, company) {
if (err || !company) {
console.log(err);
req.flash("error", err.message);
res.redirect("/");
} else {
console.log("Request to edit company.");
//console.log(company);
res.render("company/edit", {title: "Edit Company", company: company});
}
});
});
This is what I am getting if I console log company:
{ _id: 5a070874b4292914444b6e06,
name: 'ABC',
__v: 1,
clients:
[ { username: 'abcdefg#gmail.com',
_id: 5a070206616810129b5c876a } ],
staff: [],
active: true,
created: 2017-11-11T14:25:56.359Z }
Thanks for your help.
Your company schema should look like this
var companySchema = new mongoose.Schema ({
...
staff: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
clients: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }]
});
See the docs http://mongoosejs.com/docs/populate.html
Im receiving a maximum call stack size exceeded error while working with mongoose and Nodejs. here is the error
RangeError: Maximum call stack size exceeded
at model.Document.$toObject (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2045:24)
at model.Document.toJSON (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2362:15)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:252:18)
at cloneArray (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:362:14)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:247:12)
at cloneObject (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:343:13)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:260:16)
at model.Document.$toObject (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2092:13)
I believe this means that I'm causing an infinite loop somewhere, but I am unsure what is causing the error. The route worked correctly, then I added the mongoose-autopopulate plugin to the app. When sending a POST correctly with a token to my drive post route, I recieve this error. Nothing is logged and the server stops.
Here is an example of my route in drive.js
router.post('/', function(req, res, next){
var decoded = jwt.decode(req.query.token);
User.findById(decoded.user._id, function(err, user){
if (err) {
return res.status(500).json({
title: 'There was a server error',
error: err
});
}
var drive = new Drive({
startAddress: req.body.startAddress,
endAddress: req.body.endAddress,
tripDate: req.body.tripDate,
tripHour: req.body.tripHour,
price: req.body.price,
numberOfPassengers: req.body.numberOfPassengers,
user: user
});
drive.save(function (err, result) {
if(err) {
return res.status(500).json({
title: 'There was an error saving the drive collection',
error: err
});
}
user.drives.push(result);
user.save();
res.status(201).json({
message: 'Drive saved',
obj: result
});
});
});
});
And here is the related model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.model');
var Trip = require('./trip.model');
var autoPopulate = require('mongoose-autopopulate');
var driveSchema = new Schema({
startAddress: {type: String, required: true, lowercase: true},
endAddress: {type: String, required: true, lowercase: true},
tripDate: {type: Date, required: true},
tripHour: {type: String, required: true},
price: {type: Number, required: true},
numberOfPassengers: {type: Number, required: true},
trip: {type: Schema.Types.ObjectId, ref: 'Trip', autopopulate: true},
user: {type: Schema.Types.ObjectId, ref: 'User', autopopulate: true}
});
driveSchema.post('remove', function(drive) {
User.findById(drive.user, function(err, user) {
user.drives.pull(drive);
user.save();
});
});
driveSchema.plugin(autoPopulate);
module.exports = mongoose.model('Drive', driveSchema);
All of my models follow the same methods and queries. Is there anything in specific I am doing wrong? I looked it up and it seems that I could be calling an instance instead of JSON which breaks the code, but Im not experienced enough to identify where that instance is, or whats causing a reocurring call as .find() or .where() that I am using that is breaking it.
Here are my other models
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var autopopulate = require('mongoose-autopopulate');
var tripSchema = new Schema({
tripActivated: {type: Boolean},
tripCompleted: {type: Boolean},
driver: {type: Schema.Types.ObjectId, ref: 'Drive', autopopulate: true},
riders: [{type: Schema.Types.ObjectId, ref: 'Ride', autopopulate: true}],
comments: [{type: Schema.Types.ObjectId, ref: 'Comment', autopopulate: true}]
});
tripSchema.post('remove', function(trip) {
User.findById(trip.driver.user, function(err, user) {
user.trips.pull(trip);
user.save();
});
});
// tripSchema.post('remove', function(trip) {
// User.findById(trip.riders.user, function(err, user) {
// user.trips.pull(trip);
// user.save();
// });
// });
tripSchema.plugin(autopopulate);
module.exports = mongoose.model('Trip', tripSchema);
//// NEW MODEL
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.model');
var Trip = require('./trip.model');
var autoPopulate = require('mongoose-autopopulate');
var rideSchema = new Schema({
startAddress: {type: String, required: true, lowercase: true},
endAddress: {type: String, required: true, lowercase: true},
tripDate: {type: Date, required: true},
tripHour: {type: String, required: true},
numberOfPassengers: {type: Number, required: true},
trip: {type: Schema.Types.ObjectId, ref: 'Trip', autopopulate: true},
user: {type: Schema.Types.ObjectId, ref: 'User', autopopulate: true}
});
rideSchema.post('remove', function(ride) {
User.findById(ride.user, function(err, user) {
user.rides.pull(ride);
user.save();
});
});
rideSchema.plugin(autoPopulate);
module.exports = mongoose.model('Ride', rideSchema);
////// NEW MODEL
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.model');
var autoPopulate = require('mongoose-autopopulate');
var requestSchema = new Schema({
typeOfRequest: {type: String, required: true},
driver: {type: Schema.Types.ObjectId, ref: 'Drive', autopopulate: true},
rider: {type: Schema.Types.ObjectId, ref: 'Ride', autopopulate: true}
});
requestSchema.post('remove', function(request) {
User.findById(request.user, function(err, user) {
user.requests.pull(request);
user.save();
});
});
requestSchema.plugin(autoPopulate);
module.exports = mongoose.model('Request', requestSchema);
//// NEW MODEL
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var autoPopulate = require('mongoose-autopopulate');
var User = require('./user.model');
var messageSchema = new Schema ({
content: {type: String, required: true},
receiver: {type: Schema.Types.ObjectId, ref: 'User', autopopulate: true },
user: {type: Schema.Types.ObjectId, ref: 'User', autopopulate: true}
});
messageSchema.post('remove', function(message) {
User.findById(message.user, function(err, user) {
user.messages.pull(message);
user.save();
});
});
messageSchema.plugin(autoPopulate);
module.exports = mongoose.model('Message', messageSchema);
Upon diving deeper, my error seems to stem from this code that is starred in the mongoose source code in node_modules
Document.prototype.$toObject = function(options, json) {
***var defaultOptions = {
transform: true,
json: json,
retainKeyOrder: this.schema.options.retainKeyOrder,
flattenDecimals: true
};***
// _isNested will only be true if this is not the top level document, we
// should never depopulate
if (options && options.depopulate && options._isNested && this.$__.wasPopulated) {
// populated paths that we set to a document
return clone(this._id, options);
}
// When internally saving this document we always pass options,
// bypassing the custom schema options.
if (!(options && utils.getFunctionName(options.constructor) === 'Object') ||
(options && options._useSchemaOptions)) {
if (json) {
options = this.schema.options.toJSON ?
clone(this.schema.options.toJSON) :
{};
options.json = true;
options._useSchemaOptions = true;
} else {
options = this.schema.options.toObject ?
clone(this.schema.options.toObject) :
{};
options.json = false;
options._useSchemaOptions = true;
}
}
for (var key in defaultOptions) {
if (options[key] === undefined) {
options[key] = defaultOptions[key];
}
}
('minimize' in options) || (options.minimize = this.schema.options.minimize);
// remember the root transform function
// to save it from being overwritten by sub-transform functions
var originalTransform = options.transform;
options._isNested = true;
var ret = clone(this._doc, options) || {};
if (options.getters) {
applyGetters(this, ret, 'paths', options);
// applyGetters for paths will add nested empty objects;
// if minimize is set, we need to remove them.
if (options.minimize) {
ret = minimize(ret) || {};
}
}
if (options.virtuals || options.getters && options.virtuals !== false) {
applyGetters(this, ret, 'virtuals', options);
}
if (options.versionKey === false && this.schema.options.versionKey) {
delete ret[this.schema.options.versionKey];
}
var transform = options.transform;
// In the case where a subdocument has its own transform function, we need to
// check and see if the parent has a transform (options.transform) and if the
// child schema has a transform (this.schema.options.toObject) In this case,
// we need to adjust options.transform to be the child schema's transform and
// not the parent schema's
if (transform === true ||
(this.schema.options.toObject && transform)) {
var opts = options.json ? this.schema.options.toJSON : this.schema.options.toObject;
if (opts) {
transform = (typeof options.transform === 'function' ? options.transform : opts.transform);
}
} else {
options.transform = originalTransform;
}
if (typeof transform === 'function') {
var xformed = transform(this, ret, options);
if (typeof xformed !== 'undefined') {
ret = xformed;
}
}
return ret;
};
I set mongoose.set('debugger', true); to get a better error. When attempting to post on ride.js, the app registers the POST request, finds the userID, handles the new Ride (based off model), inserts the ride into the database, and then crashes immediately after.
here is the error with mongoose logs
Mongoose: users.ensureIndex({ email: 1 }, { unique: true, background: true })
Successfully connected to localhost:27017/atlas
Mongoose: users.findOne({ _id: ObjectId("59506e1629cdff044664f21c") }, { fields: {} })
(node:1219) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
Mongoose: rides.insert({ startAddress: 's', endAddress: 's', tripDate: new Date("Fri, 22 Feb 2222 00:00:00 GMT"), tripHour: '8', numberOfPassengers: 2, user: ObjectId("59506e1629cdff044664f21c"), _id: ObjectId("595078cf0b46e704c3091070"), __v: 0 })
events.js:160
throw er; // Unhandled 'error' event
^
RangeError: Maximum call stack size exceeded
at model.Document.$toObject (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2045:24)
at model.Document.toJSON (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2362:15)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:253:18)
at cloneArray (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:363:14)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:247:12)
at cloneObject (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:344:13)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:261:16)
at model.Document.$toObject (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2092:13)
at model.Document.toJSON (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2362:15)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:253:18)
at cloneObject (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:344:13)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:261:16)
at model.Document.$toObject (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2092:13)
at model.Document.toJSON (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/document.js:2362:15)
at clone (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:253:18)
at cloneArray (/Users/joncorrin/Desktop/workspace/MEAN/atlas-web/node_modules/mongoose/lib/utils.js:363:14)
**********UPDATE
After doing some digging, this is the code thats breaking the app
user.drives.push(result); <----------
user.save();
Its the inserting the data into mongodb and then when it tries to push to the user, it breaks. Any idea why?I added my user model for reference.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var mongooseUniqueValidator = require('mongoose-unique-validator');
var autoPopulate = require('mongoose-autopopulate');
var userSchema = new Schema({
email: {type: String, required: true, unique: true, lowercase:true},
password: {type: String, required: true},
profileImgUrl: {type: String},
fName: {type: String},
lName: {type: String},
yearOfBirth: {type: String},
gender: {type: String},
ratings: [{type: Number}],
comments: [{type: Schema.Types.ObjectId, ref: 'Comment', autopopulate: true}],
messages: [{type: Schema.Types.ObjectId, ref: 'Message', autopopulate: true}],
rides: [{type: Schema.Types.ObjectId, ref: 'Ride', autopopulate: true}],
drives: [{type: Schema.Types.ObjectId, ref: 'Drive', autopopulate: true}],
requests: [{type: Schema.Types.ObjectId, ref: 'Request', autopopulate: true}],
trips: [{type: Schema.Types.ObjectId, ref: 'Trip', autopopulate: true}]
});
userSchema.plugin(mongooseUniqueValidator);
userSchema.plugin(autoPopulate);
module.exports = mongoose.model('User', userSchema);
The issue was in my user model. I was using the mongoose-autopopulate plugin and setting autopopulate to true objects that had a user instance in them.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var mongooseUniqueValidator = require('mongoose-unique-validator');
var autoPopulate = require('mongoose-autopopulate');
var userSchema = new Schema({
email: {type: String, required: true, unique: true, lowercase:true},
password: {type: String, required: true},
profileImgUrl: {type: String},
fName: {type: String},
lName: {type: String},
yearOfBirth: {type: String},
gender: {type: String},
ratings: [{type: Number}],
comments: [{type: Schema.Types.ObjectId, ref: 'Comment', autopopulate: true}],
messages: [{type: Schema.Types.ObjectId, ref: 'Message', autopopulate: true}],<---------
rides: [{type: Schema.Types.ObjectId, ref: 'Ride', autopopulate: true}],<---------
drives: [{type: Schema.Types.ObjectId, ref: 'Drive', autopopulate: true}],<-----------
requests: [{type: Schema.Types.ObjectId, ref: 'Request', autopopulate: true}],
trips: [{type: Schema.Types.ObjectId, ref: 'Trip', autopopulate: true}]
});
userSchema.plugin(mongooseUniqueValidator);
userSchema.plugin(autoPopulate);
module.exports = mongoose.model('User', userSchema);
I was also setting autopopulate to true on those models. This was calling an infinite loop between populating the model given, and the user model.
If anyone is having this issue. Don't be like me and post a bunch of code on stack overflow. Figure out what you're calling that's recalling the call. In my case, I was calling autopopulate on two models that would communicate back and forth.