mongoose: mongoose.connect() doesn't return a promise in Angular universal, when using 'srv' in uri string
in server.ts (express server):
import mongoose from "mongoose"
app.get("/articles/api/*", (req, res) => {
console.log("aaa")
mongoose.connect(uri,{}) //uri is the connection string
.then(db=>{
console.log("connected")
db.model(...)
})
.catch(error=>console.log(error))
//res.send(...)
});
neither .then() nor .catch() is called, but ‘aaa’ is called, means that the express path works fine
note1: running this code outside of angular works fine
note2: console.log(mongoose.connect(uri)) in Angular returns zone (not promise):
ZoneAwarePromise { __zone_symbol__state: null, __zone_symbol__value: [] }
when replacing mongoose.connect(…) with new Promise(r=>r()) it works fine
update: when removing +srv from the connection string it works with error i.e: catche() runs, but with ‘srv’ neither .then() or .catch() runs
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 2
- Comments: 23
Remove Zone.js until these changes land in a new release of the mongodb node driver and Mongoose picks up those changes. Unfortunately the issue is with a non-exported variable deep in the MongoDB driver, so there’s no way to work around this issue until the mongodb driver releases a fix.
This should be fixed in Mongoose 5.7.10 👍
Here’s what I did to work around this problem, perhaps it will be useful to someone.
Since in my Node back-end Zone.js was only required for Angular Universal and nothing else, I only needed to find a way to run the rendering process in an isolated JavaScript environment. This could be easily achieved via a child process. Here’s the basic idea in steps:
process.on
andprocess.send
in such a way that when the parent sends a “render request”, this little process would perform the render and send a message back, which would contain the rendered HTML.fork
fromchild_process
.app.engine
.I can elaborate and share pieces of code if needed, but not the whole thing as its a commercial project.
Also, disclaimer - not battle-tested, although right now I can’t see why this would not work.
@juona we’re still waiting on the mongodb driver to release our patch. Unfortunately there’s no workaround currently besides disabling zone.js or not using Atlas
Will investigate this more. But just FYI, you shouldn’t call
mongoose.connect()
in a route handler, see this FAQUsing the non-SRV URL from Mongo Atlas to connect doesn’t call any callback as well.
mongodb://<username>:<password>@test-dev-shard-00-00-kboew.mongodb.net:27017,test-dev-shard-00-01-kboew.mongodb.net:27017,test-dev-shard-00-02-kboew.mongodb.net:27017/test?ssl=true&replicaSet=test-dev-shard-0&authSource=admin&retryWrites=true&w=majority
Has anyone found a workaround?
@vkarpov15
How hard would it be to determine whether an issue that I am facing is caused by the same underlying problem?
I have created a truly simple (single-file) demo repo (https://github.com/juona/mongoose-zonejs).
The problem is that when I use Mongoose in combination with Zone.js (same as @xxyyzz2050 ), and try to connect to a cluster (replica set) on Atlas, it does not work - the program simply exits. My investigation has not yielded much - it appears that the handshake requests are sent to the socket yet I do not receive any responses, after which the application decides that it has run to completion and exits without printing anything. It feels like “the execution context is lost” at some point due to an incompatibility with Zone.js but I haven’t been able to find where.
This does not happen if I connect to the same cluster (same URL) using the official MongoDB driver or if I do not use Zone.js.
This does not happen when connecting to a simple MongoDB server hosted locally. I also tried hosting a replica set on my machine and connecting to it using a non-SRV URL, and it works just fine. However, using a non-SRV URL to connect to Atlas does not help.
I also encountered the same problem…