4

I am using mongoose to handle my schemas, with MongoDB, but when trying to save a new entry to a collection the save() method appears to be stuck, neither the then() method or the catch() method of the promise appear to be called.

Does anyone have any ideas?

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// const Promise = require('bluebird');

const config = require('./config');

const UserSchema = new Schema({
    email: { type: String, required: true, index: { unique: true } },   
    name: { type: String, required: false },
    password: { type: String, required: true }
});

const User = mongoose.model('User', UserSchema);

console.log('config.database.url', config.database.url);

mongoose.Promise = global.Promise;
return mongoose.createConnection(config.database.url, {
    useMongoClient: true
})
.then((connection) => {
    const user = new User({
        email: 'someuser@somedomain.com',
        password: 'xxxxx'
    });

    const prom = user.save();

    // Displays: 'promise: Promise { <pending> }'
    console.log('promise:', prom);

    return prom
    .then((result) => {
        // Don't see this output
        console.log('result:', result);
    })
    .catch((error) => {
        // Don't see this output either
        console.log('error:', error);
    });
})
.catch((error) => {
    console.log(error);
});

Environment: nodejs 8.9.0, node modules: Mongoose 4.13.6, mongodb 2.2.33

Andre M
  • 6,649
  • 7
  • 52
  • 93
  • Have a callback to save method and console error parameter to know whats wrong. Also `return prom` is basically terminating your function so its obvious remaining code is not executing – wrangler Dec 07 '17 at 23:04
  • I don't see anything wrong with the *pending* thing. It's async code after all, and the console.log is called before save is finished. You can change `createConnection` with `connect` to make it save. – Mika Sundland Dec 07 '17 at 23:07

1 Answers1

4

A little more experimenting and it would appear that I need to ensure the model is tied to the connection, such that:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// const Promise = require('bluebird');

const config = require('./config');

const UserSchema = new Schema({
    email: { type: String, required: true, index: { unique: true } },   
    name: { type: String, required: false },
    password: { type: String, required: true }
});

let User;

console.log('config.database.url', config.database.url);

mongoose.Promise = global.Promise;

return mongoose.createConnection(config.database.url, {
    useMongoClient: true
})
.then((connection) => {
    // associate model with connection
    User = connection.model('User', UserSchema);

    const user = new User({
        email: 'someuser@somedomain.com',
        password: 'xxxxx'
    });

    const prom = user.save();

    // Displays: 'promise: Promise { <pending> }'
    console.log('promise:', prom);

    return prom
    .then((result) => {
        // Don't see this output
        console.log('result:', result);
    })
    .catch((error) => {
        // Don't see this output either
        console.log('error:', error);
    });
})
.catch((error) => {
    console.log(error);
});

Alternatively we should use the connect() method that will work with the model associated via mongoose.model.

For createConnection() can be used to create multiple connections, so using a 'global' model is not supported, from what I can tell.

Saying all this it would be nice if save() didn't simply block.

Note: In researching a refinement to my answer I came across the following: Queries hang when using mongoose.createConnection() vs mongoose.connect()

Andre M
  • 6,649
  • 7
  • 52
  • 93