Using "mongoose": "^4.11.7".
To run the script, I'm using babel-node
.
Do you want to request a feature or report a bug?
bug, maybe.
What is the current behavior?
Cannot read property 'Types' of undefined
authorId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
^
If the current behavior is a bug, please provide the steps to reproduce.
I've defined the schema like this:
import * as mongoose from 'mongoose';
const Schema = mongoose.Schema;
const RecipeSchema = new Schema ({
authorId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
name: String,
description: String,
photos: [
{
name: String,
path: String,
isMain: Boolean,
alt: String
}
],
ingredients: [
{
name: String,
quantity: Number,
metricType: {
type: String,
enum: [ 'kg', 'g', 'mg', 'l', 'ml', 'unit' ],
default: 'unit'
}
}
],
preparement: String,
isForSell: { type: Boolean, required: true, default: false },
price: Number,
url: String,
portionNumber: Number,
time: Number,
grades: [
{
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
grade: Number,
date: Date
}
],
} );
export default mongoose.model ( 'Recipe', RecipeSchema );
And tried to seed the database with a function like this:
async function insert_recipe () {
const user = await User.findOne ( {} );
await Recipe.create ( {
authorId: user.id,
name: 'some name',
description: 'some description',
ingredients: [
{
name: 'foo',
quantity: 12,
metricType: 'g'
},
{
name: 'bar',
quantity: 50,
metricType: 'g'
}
],
preparement: 'how to do something like this',
isForSell: false,
portionNumber: '5',
time: 20,
What is the expected behavior?
It should use the first user's ID that owns the recipe and create the recipe itself on the database.
Please mention your node.js, mongoose and MongoDB version.
I'm using the last versions for all of them in the current moment. (2017-09-15)
can you try without babel-node
and just do const mongoose = require('mongoose')
and see if that works?
Confirmed. In the future, if you expect someone to use babel to run your code then please provide your .babelrc / babel config so we don't have to guess what presets you're using. The answer is to do this:
import mongoose from 'mongoose';
Instead of this:
import * as mongoose from 'mongoose';
There is a very subtle and insidious difference between import
and import *
that is very bad for libs like mongoose that rely on sane binding. At a high level, the below two are equivalent
import * as mongoose from 'mongoose';
// is roughly equivalent to:
import t from 'mongoose';
const mongoose = Object.assign({}, t);
Which is bad because mongoose libs and constructors assume in a lot of places that they're bound to an instance of the internal Mongoose
constructor rather than an arbitrary object. Here's another example, let's say you have a file export.js
that looks like this:
module.exports = new Date();
module.exports.foo = function() { console.log('hello'); };
Assuming the below babelrc:
{
"presets": ["es2015"]
}
The below file will print that t
is a Date object:
import t from './export';
// t.constructor.name === 'Date'
console.log(t, t.constructor.name, t.foo());
But the below file will print that t
is a generic object:
import * as t from './export';
// t.constructor.name === 'Object'
console.log(t, t.constructor.name, t.foo());
TLDR; use import mongoose from 'mongoose';
, do not use import *
How about babel 7 ? the specification of babelrc changed.
I use import mongoose from 'mongoose';
and I still have this issue...
My babelrc file looks like this :
{
"presets": [
[
"@babel/preset-env",
{
"loose": true,
"targets": {
"node": "6.9"
}
}
]
],
"plugins": [
"@babel/transform-runtime",
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
]
]
}
@koraysels can you provide more code samples and provide exact versions of babel and your various presets and plugins?
I'm in the process of upgrading to babel@7 and am running into this issue (or a similar one).
Formerly, my code worked properly as follows:
import mongoose, { Schema } from 'mongoose'
But that now throws the Cannot read property 'Types' of undefined
error. Changing it to the following seems to do the trick:
import mongoose from 'mongoose';
const { Schema } = mongoose;
I've also been on mongoose@^4.9.6 and have been testing out v5. Has anything changed about the default module exports? Could babel@7 change something about what is made available.
{
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: [
[
'reflective-bind/babel',
{
log: 'debug',
},
],
[
'@babel/plugin-proposal-decorators',
{
legacy: true,
},
],
'@babel/plugin-proposal-class-properties',
'@babel/plugin-transform-runtime',
[
'babel-plugin-root-import',
{
paths: [
{
rootPathPrefix: '~',
rootPathSuffix: '.',
},
{
rootPathPrefix: '#',
rootPathSuffix: 'src',
},
],
},
],
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-syntax-import-meta',
'@babel/plugin-proposal-json-strings',
'@babel/plugin-proposal-function-sent',
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-numeric-separator',
'@babel/plugin-proposal-throw-expressions',
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-proposal-logical-assignment-operators',
'@babel/plugin-proposal-optional-chaining',
[
'@babel/plugin-proposal-pipeline-operator',
{
proposal: 'minimal',
},
],
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-do-expressions',
'@babel/plugin-proposal-function-bind',
],
}
Weird. Will investigate asap
I solved it by importing only doing
import mongoose from 'mongoose';
and then using mongoose.Schema.Types.ObjectId
instead of importing the Schema types seperately
It worked for me too that way. Thanks!
I'm in the process of upgrading to babel@7 and am running into this issue (or a similar one).
....
Since this thread is opened for a long time, maybe we could close it and open a new one for this issue.
I made some improvements so at least import mongoose, {Schema} from 'mongoose'
won't crash. There's a lot of odd quirks between the fact that Mongoose exports a non-POJO and the fact that ES2015 imports insist on POJOs. Some related issues:
Although just FYI, Mongoose _only_ supports import mongoose from 'mongoose'
. Any other import syntaxes may not work, although we're doing what we can to patch up incompatibilities.
Most helpful comment
I solved it by importing only doing
import mongoose from 'mongoose';
and then using
mongoose.Schema.Types.ObjectId
instead of importing the Schema types seperately