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

Most upvoted comments

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:

  1. Collect all the code required for Angular Universal, including Zone.js, all the Angular stuff, and whatever else, and extract that to a single file.
  2. Allow that process to communicate with its parent via process.on and process.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.
  3. The main Node application then launches the renderer using fork from child_process.
  4. Finally you have to set up the application to send rendering requests when necessary and be able to properly respond to the messages it gets back from the renderer. E.g. I am using the Express framework and basically the only thing I had to do was write an HTML engine using 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 FAQ

Using 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…