0

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"});
    })
});
3
  • If you are using mongo 3.x, and mongoose 4.x I believe they return promises by default using .exec() Commented Mar 3, 2017 at 9:30
  • yes they do, but i want to return promise from this callback or form .then i mean instead of fn(token) do Promise.resolve(token) and in my route just receive token Commented Mar 3, 2017 at 10:07
  • ah ok, I get you. Bluebird would be a good way to go then Commented Mar 3, 2017 at 13:11

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

yup that's what I though I'll do. I'll check it out later, thanks;)
1

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);
});

2 Comments

thanks, this was helpful but Andy's answer was what I was looking for.
with his response you should make a promisify function for all your find. With mine, all your mongoose functions are promisify basically.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.