Function return in NodeJS module returns undefined and it's not true

I have a mongo.js module in my NodeJS application in which I try to check if document exists, if not, save to database, if yes, return error to the routes.js file which called the module function.

Here's my module:

var appRoot = require('app-root-path'),
config = require(appRoot + '/config/config'),
db = require('mongojs').connect(config.db.host);

module.exports = {
    saveSpammer: function(ip, userAgent, fn) {
        var exist = this.find('spammers', {ip:ip, userAgent:userAgent});

        console.log(exist); // returns undefined

        if (!exist) {
            return this.save('spammers', {ip: ip, userAgent: userAgent, date: (new Date())}, fn);
        } else {
            return fn('You have already submitted a request!');
        }
    },

    save: function(col, data, fn) {
        var col = this.getCol(col);

        col.insert(data, {w:1}, function(err, records) {
            if (err) {
                return fn(err);
            } else {
                return fn(null, records);
            }
        });
    },

    find: function(col, query, fn) {
        var col = this.getCol(col);

        col.find(query, function(err, docs) {
            console.log(docs); // returns list of documents from mongo
            console.log(docs ? 1 : 0); // returns 1

            if (docs) {
                return true;
            } else {
                return false;
            }
        });
    }
}

When I output "docs" variable in find functions, i see correct data, then based on it i return true or false based on the existence of a document, the problem is that return from a function find to function saveSpammer gives me "undefined".

I am using a regular function return as in JavaScript, maybe I am missing something in the concept of NodeJS?

Please assist

The problem in your example is that the col.find() call executes asynchronously.

So

var exist = this.find('spammers', {ip:ip, userAgent:userAgent});
console.log(exist); // returns undefined

is the expected behavior since this.find does not return anything. You can see that there is no return in the definition of the find function.

You need to use the callback mechanism

this.find('spammers', {ip:ip, userAgent:userAgent}, function(err, exist) {
    console.log(exist);
    .. rest of the code here
});

and modify the find function with

if (err) {
    fn(err);
} else if (docs) {
    fn(null, true);
} else {
    fn(null, false);
}