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