Patryk Karczmarczyk
Patryk Karczmarczyk

Reputation: 55

Node.js. mongodb return promise

I am creating REST api and want to authenticate user by token. I've found tutorial and wrote function based on it. But it's on callbacks and I want to return Promise from mongoose model and in route use then rather than do callbacks. Here is my function:

UserSchema.statics.authenticate = function(login, password, fn) {
var token;
 this.findOne({login: login}, function(err, user) {
    var _token;
    if (err)
        token = ( false);

    if (!user){
      token = ( false);
    }

    else if (user)
    {
        if (user.password != password)
            token = ( false);
        else
        {
            token = jwt.sign(user, secret);
            user.update(
                { $set: {
                    token: token ,
                    lastActive: new Date()
                }}
            );
        }
    }

    fn(token);
});
};
module.exports = mongoose.model('User', UserSchema);

I know that to return promise from find function i have to usee exec() but what I want to achive is to return token do I have to var q = new Promise in function and return this q object?

This is my route

router.post('/authenticate', function(req, res, next) {
User.authenticate( req.body.login,req.body.password, function(response){
    if(response)
        res.status(200)
        .send({'success': true, token: response, msg: "Successfuly authenticated"});
    else
        res.status(200)
        .send({'success': false, token: null, msg: "Wrong username or password"});
    })
});

Upvotes: 0

Views: 489

Answers (2)

Andy Macleod
Andy Macleod

Reputation: 3049

Bluebird is a great library to handle this.

You can define a promise before a query, resolve it in the response, and yield it after.

For example:

var Promise = require('bluebird');
var defer = Promise.defer();

collection.find({name: 'name here'}).exec(function(err, result) {
    if(err){
        defer.reject(err);
    } else {
        defer.resolve(result);
    }
});

return defer.promise

Upvotes: 1

throrin19
throrin19

Reputation: 18197

The best way to use mongoose with promises is to used the bluebird npm package :

npm install --save bluebird

and to make that on your models declaration :

const Promise = require('bluebird');

//...

let Model = mongoose.model('User', UserSchema);

module.exports = Promise.promisifyAll(Model);

Now you can use all mongoose methods with promises :

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

User.find().then((users) => {
    if (users) {
        reply(null, users);
        return;
    }
    reply(null, []);
}).catch((err) => {
    reply.boom(500, err);
});

Upvotes: 1

Related Questions