It's common when user wants to import variables from module without saving module into a variable, e.g.
let {Schema} = require('mongoose');
or
var Schema = require('mongoose').Schema;
but when I do this with model
var model = require('mongoose').model;
and try to create a model with imported function, I have an error
TypeError: Cannot read property 'modelSchemas' of undefined
Yes, model is a property of Mongoose.prototype, but Schema also is.
If documentation contains an instruction like
var Schema = mongoose.Schema,
...
it's possible to assume that 'model' will have similar behavior
Supporting this behavior would involve a massive refactor of mongoose connections. Long story short, require('mongoose').model();
is different than var model = require('mongoose').model; model();
because the value of this
in the former function call is the require('mongoose');
singleton, whereas it is the global object in the latter call. If you want a workaround, model.call(require('mongoose'), 'MyModelName', schema);
should work fine. I'm not a huge fan of the fact that mongoose's top level functions are laden with side effects, but to get rid of that we'd also have to get rid of the mongoose.model()
getter syntax, which would break a lot of people's code.
@vkarpov15 thanks for your answer!
There are 2 different cases:
When we have the issue open, it can be fixed with breaking change (in new major release) or without breaking change (you know, everything can be refactored with backward compatibility, it just depends on effort). Someone (e.g. me) probably has time for it.
But when we mark the issue closed, we give contributors to know that pull requests with fixing this bug will be rejected, and someone doesn't even start to fix it.
What do you think about it?
Fair point, I'll keep this issue open. The workaround is easy, just ensure the functions have proper context. The eventual solution is no side-effects.
+1
Currently this doesn't work:
import { model } from 'mongoose'
Not expected to work in the immediate future because of side-effects in mongoose. No really good way to make mongoose.model()
work as a getter/setter if you're using import { model }
unless you use global state, which I'm loathe to do. Why don't you just use import 'mongoose';
? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
I'll +1 this.
import { model } from 'mongoose'
^ is a handy/attractive syntax.
I created #3943 as a quick fix for this. If it's acceptable (until a better solution can be created), then I can write a test to go with the PR. If it needs revised at all, I'm more than willing to.
I like the general idea, but tests fail in that pr, which is a deal breaker unfortunately
Yup, I did see that. I'll be playing with it tomorrow to see what's going
on.
On Sat, Mar 5, 2016, 17:45 Valeri Karpov [email protected] wrote:
I like the general idea, but tests fail in that pr, which is a deal
breaker unfortunately—
Reply to this email directly or view it on GitHub
https://github.com/Automattic/mongoose/issues/3768#issuecomment-192769531
.
Came across this today after trying const { model } = require('mongoose');
needless to say it didn't work so back to let foo = mongoose.model('foo',fooSchema);
Be nice if someone has time for a fix but I can see why it's not high priority!
So, to try and clarify, running
import { model } from 'mongoose';
//...
model('testModel', testModelSchema);
...exposes the model
object to the global namespace, whereas
import mongoose from 'mongoose';
//...
mongoose.model('testModel', testModelSchema);
places the model in the scope of the already connected mongoose singleton object. Can some confirm this for me please.
Thanks
@cr05s19xx that is generally correct. In the former, this
is the global namespace, but in the latter this
in model()
refers to the mongoose singleton
If this error only occurs when we have this problem, it would be beneficial to print out the cause and fix so people don't end up having to google and coming to this issue like I did.
In 5.3.14, you'll be able to do import {model} from 'mongoose'
and it will work properly. That is just for this one function though, we still need more work to support that for the rest of the Mongoose global API. We'll still warn against doing this and keep the section in the FAQ, but the model case is so frequent that we can fix it as a one-off.
Most helpful comment
+1
Currently this doesn't work: