-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Closed
Labels
confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.We've confirmed this is a bug in Mongoose and will fix it.
Milestone
Description
Prerequisites
- I have written a descriptive issue title
Mongoose version
7.0.3
Node.js version
v16.13.1
MongoDB version
4.2
Operating system
macOS
Operating system version (i.e. 20.04, 11.3, 10)
No response
Issue
When mongoose try to populate a document I have this error
TypeError: Cannot read properties of undefined (reading 'options')
at SchemaUUID._castRef (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/schematype.js:1531:19)
at SchemaUUID.cast (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/schema/uuid.js:255:17)
at _init (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/document.js:781:35)
at init (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/document.js:735:5)
at EmbeddedDocument.Document.$__init (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/document.js:694:3)
at EmbeddedDocument.syncWrapper [as $__init] (/Users/username/Projects/applications/mybackend/node_modules/kareem/index.js:331:25)
at EmbeddedDocument.Document.init (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/document.js:638:8)
at EmbeddedDocument.Document.$init (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/document.js:654:42)
at DocumentArrayPath.cast (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/schema/documentarray.js:495:30)
at _init (/Users/username/Projects/applications/mybackend/node_modules/mongoose/lib/document.js:781:35)
It du to cast function in uuid.js, it doesn't have binary or embeded case.
SchemaUUID.prototype.cast = function(value, doc, init) {
if (SchemaType._isRef(this, value, doc, init)) {
if (isBsonType(value, 'UUID')) {
return value;
}
return this._castRef(value, doc, init);
}
On stackoverflow some people talk about override it as
SchemaUUID.prototype.cast = function (value, doc, init) {
console.log("cast", value, doc, init)
if (value instanceof mongoose.Types.Buffer.Binary) {
if (init && doc instanceof mongoose.Types.Embedded) {
return getter(value);
}
return value;
}
if (typeof value === 'string') {
var uuidBuffer = new mongoose.Types.Buffer(uuidParse.parse(value));
uuidBuffer.subtype(bson.Binary.SUBTYPE_UUID);
return uuidBuffer.toObject();
}
throw new Error('Could not cast ' + value + ' to UUID.');
};
This is my user schema
'use strict';
var { randomUUID } = require('crypto');
var mongoose = require('mongoose');
var mongoosePaginate = require('mongoose-paginate-v2');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt');
var UserSchema = new Schema({
_id: { type: Schema.Types.UUID, default: () => randomUUID() },
username: {type: String, unique: true},
datacollect_id: { type: Schema.Types.UUID, required: true},
password: {type: String},
age: {type: Number},
gender: {type: String, enum: ["woman", "man"]},
handedness: {type: String, enum: ["left", "right"]},
language: { type: Schema.Types.UUID, ref: 'Language'},
isTest: {type: Boolean, required: true, default: false},
isMyScriptSSOAccount: {type: Boolean, required: true, default: false},
swipeExperience: {type: String, enum: ["never", "first_experience", "regular_user", "expert"]},
keyboardExperience: {type: String, enum: ["never", "first_experience", "regular_user", "expert"]},
created: {type: Date, default: Date.now, required: true},
creationBy: { type: Schema.Types.UUID, ref: 'User', required: true },
expirationDate: {type: Date},
updateDate: {type: Date, required: true},
enabled: {type: Boolean, required: true},
roles: {
type: [String], enum: ["USER", "SCRIPTER", "CLEANER", "COLLECTER", "ADMIN"], required: true
},
collects: [{
collect: { type: Schema.Types.UUID, ref: 'Collect', required: true},
sessions: {type: [{
stepsIndex: {type: Number, required: true},
inksCreated: {type: Number, required: true},
inksGoal: {type: Number, required: true},
beginDate: {type: Date, required: true},
endDate: {type: Date},
updateDate: {type: Date, required: true}
}]}
}]
},
{
id: false
});
UserSchema.set('toObject', {getters: true});
UserSchema.set('toJSON', {getters: true});
UserSchema.plugin(mongoosePaginate);
UserSchema.pre('save', function (next) {
var user = this;
if (this.password && (this.isModified('password') || this.isNew)) {
bcrypt.genSalt(10, function (err, salt) {
if (err) {
return next(err);
}
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) {
return next(err);
}
user.password = hash;
next();
});
});
} else {
return next();
}
});
UserSchema.methods.comparePassword = function (passw, cb) {
bcrypt.compare(passw, this.password, function (err, isMatch) {
if (err) {
return cb(err);
}
cb(null, isMatch);
});
};
module.exports = mongoose.model('User', UserSchema);
This is how I called the populate on user schema
function getUserByToken(payload, done) {
var id = payload.userId,
options = [
{path: 'language'},
{path: 'creationBy', select: '-password -collects'},
{path: "collects.collect", populate: [
{path: "language"},
{path: "creationBy", select: "-password -collects"},
{path: "steps.inputMethod.keyboard", model: "Keyboard", populate: {path: "language"}},
{path: "steps.labelsSettings.dataFormat"},
{path: "steps.labelsSettings.language"}
]}
];
User.findOne({_id: id})
.select("-password")
.populate(options)
.then(user => {
if (user) {
done(null, user);
} else {
done(null, false);
}
})
.catch(err => {
return done(err, false);
});
}
Language and collect references are in errors.
Is there a way to improve that ?
Metadata
Metadata
Assignees
Labels
confirmed-bugWe've confirmed this is a bug in Mongoose and will fix it.We've confirmed this is a bug in Mongoose and will fix it.