Adam
Adam

Reputation: 502

Calling functions in express - undefined

I am writing back-end javascript in express but for some reason my function is undefined when called. It looks like this:

//express route looks like this:

exports.check = function(req, res) { //check if username is in database
    var my_result = authenticator(req); //authenticator is defined below
    console.log(typeof(authenticator(req))); //returns undefined
};

function authenticator(req) {
    var mongoose = require('mongoose');
    var db = mongoose.createConnection('localhost', 'users');
    db.once('open', function callback() {
        var personschema = mongoose.Schema({
            username: String,
            password: String
        })
        var person1 = db.model('personcollection', personschema)
        person1.find({
            username: req.body.username,
            password: req.body.password
        }, function(err, obj) {
            if (obj.length === 0) {
                return "yay";
            } else {
                return "neigh";
            }
        } //end function

The function itself works when I put it inside the express route, but I want to keep the route pretty, with as little code as possible. Is that an option?

Thanks for your help.

Upvotes: 1

Views: 157

Answers (2)

gustavohenke
gustavohenke

Reputation: 41440

Welcome to the wonderful async world of JavaScript :)
And, even more, the Node.js world.

This happens because no networking in Node can be done synchronously - this means that you must work with callbacks.

Your authenticator function should look somewhat like this:

function authenticator(req, callback) {
    var mongoose = require('mongoose');
    var db = mongoose.createConnection('localhost','users');
    db.once('open', function() {
        var personschema = mongoose.Schema({
          username: String,
          password: String
        });

        var person1 = db.model('personcollection',personschema)
        person1.find({ username: req.body.username, password: req.body.password }, function(err, obj) {
            // in this callback you do what you want with this result!
            callback(obj.length === 0);
        });
    });
}

Two side notes:

  • What about keeping the DB connection separated? This way you'll be opening it each request.
  • You seem to be storing the plain passwords in your DB, because you're comparing them to what has been passed in the request :o You should REALLY encrypt them in your DB!

Upvotes: 3

Peter Lyons
Peter Lyons

Reputation: 146154

You are trying to return a value from an asynchronous function. Full stop. You have a fundamental misunderstanding about node.js and asynchronous programming and you need to read tutorials and wrap your head around asynchronous code and why they cannot return values and must use callbacks (or events or promises) instead.

http://nodejsreactions.tumblr.com/post/56341420064/when-i-see-some-code-that-returns-a-value-from-an-async

Upvotes: 2

Related Questions