I have a DAO (data access object) in the current project I'm working on that's an abstraction of a redis db. Here's all of the code that is going to be relevant to my upcoming question below:
var redis = require("redis");
var _ = require("underscore");
var exceptions = require("./exceptions");
function Dao (port, address) {
var self = this;
console.log("Connecting to redis @ %s:%s", address, port);
var client = redis.createClient(port, address);
function incrCount (callback) {
client.incr("count", callback);
};
this.getPages = function (callback) {
client.hgetall("pages", function (err, pages) {
if (err) {
callback(err);
} else if (!pages) {
callback(exceptions.NoPages);
} else {
callback(err, _.reduce(Object.keys(pages), function (array, id) {
array.push(JSON.parse(pages[id]));
return array;
}, []));
}
});
};
this.createPage = function (page, callback) {
incrCount(function (err, results) {
if (err) {
callback(err);
} else {
page.id = results;
self.updatePage(page);
callback(err, {id: results});
}
});
};
this.updatePage = function (page) {
client.hset("pages", page.id, JSON.stringify(page));
};
};
Whenever I use this object, for example:
function printResults (err, results) {
console.log(err || results);
};
var dao = new Dao(port, address);
dao.createPage({testpage: "testcontent"}); // DOES NOT ADD PAGE TO DB, I HAVE NOT IDEA WHY, HOWEVER COUNT IS INCREMENTED TO 1 AS IT SHOULD BE
dao.getPages(printResults); // PRINTS ERROR: NO PAGES EXIST IN DB
dao.updatePage({id: 1, testpage: "testcontent"}); // ADDS PAGE TO DB, AND THIS IS EXACTLY HOW THE FUNCTION WOULD HAVE BEEN CALLED INTERNALLY BY CREATEPAGE() ABOVE
dao.getPages(printResults); // RETURNS TEST PAGE
What makes NO SENSE is that createPage() calls updatePage() under the hood! Why are pages only created in the DB when I call updatePage() directly? createPage() doesn't actually add any pages to redis EVEN THOUGH it's also just calling updatePage(). I've stuffed my code with a million console.log() statements to log EVERYTHING to make sure I wasn't going insane, but when createPage() calls updatePage() it does so with valid arguments so I don't see what the problem could possibly be.
EDIT (SOLVED, I GUESS): Apparently the tests I was running were closing the DB before it had a chance to fully receive/process the createPage calls, I added a setTimeout(db.close(), 2000) to the end of my tests and it works now. Anti-climatic, I know.
You are not waiting on the callback for hset I would change it so it uses a callback.
this.createPage = function (page, callback) {
incrCount(function (err, results) {
if (err) {
callback(err);
} else {
page.id = results;
self.updatePage(page, function(err) {
callback(err, {id: results});
});
}
});
};
this.updatePage = function (page, callback) {
client.hset("pages", page.id, JSON.stringify(page), callback);
};
Then change your code to see if it makes any difference
var dao = new Dao(port, address);
dao.createPage({testpage: "testcontent"}, function(err, page) {
if (err) {
return console.log(err)
}
dao.getPages(printResults);
});
The problem with the below code is getPages may be called before the incr and hset are done, so it returns no pages.
dao.createPage({testpage: "testcontent"});
dao.getPages(printResults);