Mongoose : Error referencing sub schema - node.js

My user model
'use strict';
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var UserSchema = new mongoose.Schema({
id: String,
username: String,
firstName: String,
lastName: String,
initials: String,
password: String,
age: Number,
dateJoined: Date,
contactNo: String,
email: String,
about: String,
groupId: Number,
adminMode: Boolean,
simpulPoints: Number,
})
//Define model for user
const User = {
UserModel: mongoose.model("user", UserSchema),
}
module.exports = {
UserSchema : UserSchema,
User : User
}
My Events Model
'use strict';
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var UserSchema = require("../models/user").UserSchema
var EventSchema = new mongoose.Schema();
EventSchema.add({
id: String,
title: String,
description: String,
organizerId: String, //Simpul admin user responsible for event
startDate: Date, //MM-DD-YYYY HH:MM:SS:sssZ
endDate: Date,
group: String,
locaction: String,
googleMapsLink: String,
hasPassed: Boolean,
attendees: Number,
registeredUsers: [UserSchema],
groupId: Number,
adminMode: Boolean,
simpulAward: Number,
});
//Define model for evnt
var Event = {
EventModel : mongoose.model("event", EventSchema),
}
module.exports = {
Event : Event,
EventSchema : EventSchema
}
I'm getting the infamous "throw new TypeError('Invalid value for schema Array path" error with the 'registeredUsers' field. I've followed multiple posts with the same problem and can't seem to find where I am going wrong. According to my knowledge, I've exported the schemas appropriately. Any help/tips welcome

I ended up moving the Schema declarations out into a separate file and it seemed to do the trick. Suspect it must have been some file rights issue VSCode had with the users.js file

Related

Require one field, if another doesn't exists

To post a message to MongoDB i need to send a schema with a required text field. But even media field exists (as optional) - you can send request without text field. How should I do it? Here is a code:
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var Message = new Schema({
text: {type: String, required: true},
media: {type: Object, required: false}
})
You can try this using function validation as mentioned here
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var Message = new Schema({
text: {
type: String,
required: function() {
return !this.media;
}
},
media: {
type: Object,
required: function() {
return !this.text;
}
})

Error when using _id as a property type in a Mongoose Schema

I am learning MongoDB and mongoose at the moment. I have a Archive and a User schema in mongoose:
archive.js
var mongoose = require('mongoose');
var User = require('../users/user');
var notesSchema = new mongoose.Schema({
author: User.userId,
text: String,
files:[String]
});
var archiveSchema = new mongoose.Schema({
name: String,
priority: String,
deadline: Date,
status: String,
assigned_memnbers: [User.userId],
notes: [notesSchema],
});
archiveSchema.virtual('archiveId').get(function() {
return this._id;
});
module.exports = mongoose.model('Archive', archiveSchema);
user.js:
var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
username: String,
mail: String,
bio: String,
password: String
});
userSchema.virtual('userId').get(function() {
return this._id;
});
module.exports = mongoose.model('User', userSchema);
When I run my server i get the error
TypeError: Invalid value for schema path `author`, got value "undefined"
The the problem comes from author: User.userId, but I don't know how to make a reference between the two tables.
For reference, here is what my complete db design more or less looks like:
Any input on how to solve this problem or improve the overall design is welcome. Thanks you.
I think what you're talking about is a reference to other collection:
author: { type: Schema.Types.ObjectId, ref: 'User' }
and
assigned_members: [{ type: Schema.Types.ObjectId, ref: 'User' }]
should work fine.
Source: Mongoose population
I faced the same issue.I had imported a module, It was just not exporting from another module. so I have added:
exports.genreSchema = genreSchema;

findById in Mongoose on a subdocument

I am attempting a findById in Mongoose on a subdocument....[posts]
How do i findById one specific [post] inside user?
var postSchema = new mongoose.Schema({
title: String,
content: String
});
var userSchema = new mongoose.Schema({
email: String,
name: String,
posts: [postSchema]
});
You could use the dot notation something like this
unique_id = req.params.id
const uniquePost = User
.find({'posts._id':unique_id })
or if you hade a schema like this nesting
var userSchema = new mongoose.Schema({
email: String,
name: String,
posts: {
posts: postSchema
}
});
you coulld again use dot notation to find the deeply nested id
like so
const uniquePost = User
.find({'posts.posts._id':unique_id })

Aggregation and populate using mongoose

I have two collection like this:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var GradeSchema = new Schema({
gID: { type: Number, ref: 'User'},
grade: Number,
created_at: Date,
updated_at: Date,
type: Number
});
var Grade = mongoose.model('Grade', GradeSchema);
module.exports=Grade;
and:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var UserSchema = new Schema({
name: String,
lastName:String,
uID: { type: Number,ref:'Grade' },
phone: String
});
var User = mongoose.model('User', UserSchema);
module.exports=User;
how can i first aggregate and then populate to have both collection information??
i used this command using $lookup in mongodb and it return my suggested documents:
db.grades.aggregate([{$lookup
{from:"users",localField:"gID",foreignField:"uID",as: "result"}},{$match:
{"type":0}},{"$sort":{"grade":-1}}])
but when i used this in mongoose the "result" is [] and connection to user collection is failed:
Grade.aggregate([{"$lookup":
{"from":"User","localField":"gID","foreignField":"uID","as": "result"}},
{"$match":{"type":3}},{"$sort":{"grade":-1}}]).exec(function(err, data)
{console.log(data);});

How can i generate child model in mongoose

I'm trying to model the following.
I have a parent model that is called Brick that has some attributes.
There will be 5+ type of bricks that will all have their own specific attributes wich are needed also.
I want to be able to select all Bricks of a certain custumer id later, whatever the type (TwitterBrick, facebookBrick et cetera) is.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// set up a mongoose model
module.exports = mongoose.model('Brick', new Schema({
type: String,
userid: { type: String, required: true},
animationspeed: { type: Number, min: 1, max: 100 },
socialsite: String, // none, twitter, instagram
socialsearchtags: String,
tagline: { type: String, minlength:3,maxlength: 25 },
}));
An example for a child is TwitterBrick.
for now it is:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = mongoose.model('TwitterBrick', new Schema({
bgColor1: String,
bgColor2: String,
bannerBgColor1: String,
bannerBgColor2: String,
}));
TwitterBrick should inherit the attributes of Brick , but i don't know how..
Can you help me in the right direction?
Thanks!
Steven
My solution was to set a new "content" field in brickSchema, and split in different files:
brick.schema.js
var mongoose = require('mongoose');
module.exports = {
type: String,
userid: { type: String, required: true},
animationspeed: { type: Number, min: 1, max: 100 },
socialsite: String, // none, twitter, instagram
socialsearchtags: String,
tagline: { type: String, minlength:3,maxlength: 25 },
content: {type:mongoose.Schema.Types.Mixed, required: false, default: null}
}
brick.model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BrickSchema = new Schema(require('brick.schema.js'));
module.exports = mongoose.model('defaultBrick', BrickSchema, 'Bricks');
twitterBrick.model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var brickSchema = require('brick.schema.js');
brickSchema.content = new Schema({
bgColor1: String,
bgColor2: String,
bannerBgColor1: String,
bannerBgColor2: String,
});
var BrickSchema = new Schema(require('brick.schema.js'));
module.exports = mongoose.model('twitterBrick', BrickSchema, 'Bricks');
Hope it helps !
Just add the Brick model as an attribute (composition).
It will compensate for that.
Or just rely on exisiting mongoose plugins for that https://github.com/briankircho/mongoose-schema-extend
check this one out.
That's because you didn't "require" the previous file, so technically it's out of scope and the TwitterWallBrickSchema doesn't have a clue what's a "BrickSchema".
Either you put the two models in the same file , or require the first file in the second file.

Resources