For my webapp, I'm using Redis to store data and I'm having trouble making my functions (that have async calls to Redis within them) emit events upon the query being completed.
I have put all of database config in one module, with the methods defined in the same place.
Here is my code:
/* Redis config and connect */
var REDIS_URL = 'REDIS_CONFIG_STRING';
var rtg = require('url').parse(REDIS_URL);
var redis = require('redis').createClient(rtg.port, rtg.hostname);
redis.auth(rtg.auth.split(":")[1]);
/* Read the users.json file into redis */
var loadJson = function(JSON) {
if (JSON === 'DEFAULT') JSON = DEFAULT_JSON;
var users = require(JSON);
for (var key in users) {
if(users.hasOwnProperty(key)) {
redis.set(key, JSON.stringify(users[key]));
}
}
};
/* Do something to all keys in redis */
var allKey = function(callback) {
callback = callback || console.log;
redis.keys('*', function (err, keys) {
if (err) return console.log(err);
for(var i = 0, len = keys.length; i < len; i++) {
callback(keys[i]);
}
});
};
/* Get a key and something to it */
var getKey = function(key, callback) {
redis.get(key, function(err, result) {
callback(result);
});
};
/* Set a key to the value */
var setKey = function(key, value) {
redis.set(key, value);
};
/* Read the whole redis db into a json */
var toJson = function(obj) {
allKey(function(key) {
getKey(key, function(result) {
obj[key] = JSON.parse(result);
});
});
};
exports.client = redis;
exports.loadJson = loadJson;
exports.allKey = allKey;
exports.getKey = getKey;
exports.setKey = setKey;
exports.toJson = toJson;
The idea is to have something along the lines of:
db = require('./models/redis.js');
db.toJson(obj).on('complete', function() {...});
and doing the same thing to other exported functions, so that all the database connection is kept clean and separate in its own module.
How can I assign event emitters to those functions?
The problem that I'm having right now is that I end up making use of the newly created JS object (using toJson()) before it is done being filled up from the Redis db.
Solved the problem by redefining the toJson() method to the following:
var toJson = function(cb) {
//Retrieve all keys
client.keys('*', function (err, keys) {
//Error check
if (err) return console.log(err);
//Retrieve all values for the array of keys
client.mget(keys, function(err, reply) {
//Create a new object to enter the data into
var obj = {};
//Fill the obj with key-value pairs
for (var i = 0; i < keys.length; i++) {
obj[keys[i]] = JSON.parse(reply[i]);
}
//console.log(obj);
//Execute callback which makes use of the object
cb(obj);
});
});
};
However, I am still unsure if this is the best solution. Would defining event emitters be a better way of doing this?