0

mongoose 4.0.3
node 0.10.22
mongod db version 3.0.1

I'm trying to drop a collection using moongoose, but it isn't working

run: function() {
    return Q(mongoose.connect('mongodb://127.0.0.1:27017/test',opts))
    .then(function(data){
        return Q(mongoose.connection.db.dropCollection('departments'))
        .then(function(data2){
            console.log('data2 is ',data2);
            return Q(true);
        }).catch(function(err){
            console.log('err is',err);
            return Q(false);
        });
    }).catch(function(err){
        console.log('err is', err);
        return Q(false);
    });
}

This returns data2 is undefined

I tried to follow the answers based on this question :Mongoose.js: remove collection or DB

Community
  • 1
  • 1

2 Answers2

1

I think you misunderstand the way mongoose, db and Q can interact.

you can try (not tested)

run: function() {
  return Q(mongoose.connect('mongodb://127.0.0.1:27017/test',opts).exec())
  .then(function(){
    var db = mongoose.connection.db;
    var drop = Q.nbind(db.dropCollection, db);
    return drop('departments')
           .then(function(data2){
             console.log('data2 is ',data2);
             return true;
            }).catch(function(err){
             console.log('err is',err);
             return false;
             });
}).catch(function(err){
    console.log('err is', err);
    return false;
});

}

a mongoose function needs to be called with exec() in order to return a Promise.

this does not extend to the dropCollection method as far as I know so you need to de-nodeify it.

Jerome WAGNER
  • 21,986
  • 8
  • 62
  • 77
1

I don't think you can use Q this way.

Q() turns anything you pass to it into a promise. When you pass in a function call the way you do it, you effectively pass in that function's return value. In other words, just like Q(3) will resolve to 3, Q(nodefunc(args)) will resolve to whatever nodefunc(args) returns - and in case of asynchronous functions that isn't particularly much.

I suppose you want to use ninvoke (a.k.a. nsend) instead.

Q.ninvoke(object, methodName, ...args)

Alias: Q.nsend

Calls a Node.js-style method with the given variadic arguments, returning a promise that is fulfilled if the method calls back with a result, or rejected if it calls back with an error (or throws one synchronously).

The mongoose API docs say that connect is a synchronous method that returns nothing. Its close cousin createConnection will return a connection object and might be a better fit for the use case.

The following code has both - a call to Q for a synchronous method that returns an actual value, and a call to Q.nsend for an asynchronous method that works with callbacks.

run: function() {
    return Q(mongoose.createConnection('mongodb://127.0.0.1:27017/test', opts))
    .then(function(connection){
        return Q.nsend(connection.db, 'dropCollection', 'departments')
        .then(function(data){
            console.log('data is ', data);
            return data;
        });
    }).catch(function(err){
        console.log('err is', err);
    });
}

(untested code)

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • `connection` comes out undefined. If you use `mongoose.connection.db` instead of `connection.db` there, it works fine –  Jun 03 '15 at 16:49
  • @Houseman Ahh, I see. `mongoose.connect` is a synchronous function (didn't know, I don't do a lot with mongoose). In that case you don't need to promisify it at all (unless you want to use Q's `.catch()`). – Tomalak Jun 03 '15 at 17:04