Mongoose: Allow `import { model } from mongoose`

Created on 16 Jan 2016  ·  14Comments  ·  Source: Automattic/mongoose

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

enhancement

Most helpful comment

+1

Currently this doesn't work:

import { model } from 'mongoose'

All 14 comments

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:

  1. We know it's a bug, but fixing it takes a time for refactoring. Then we should keep the issue open
  2. We assert it is not a bug. Then we should close the issue

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

p3x-robot picture p3x-robot  ·  3Comments

lukasz-zak picture lukasz-zak  ·  3Comments

ArThoX picture ArThoX  ·  3Comments

gustavomanolo picture gustavomanolo  ·  3Comments

adamreisnz picture adamreisnz  ·  3Comments