I can’t figure out why the fetch function is not returning the information I wish to have:
(function(){
var root = this;
var Database = root.Database = {};
var Db = require('mongodb').Db,
Connection = require('mongodb').Connection,
Server = require('mongodb').Server;
var host = process.env['MONGO_NODE_DRIVER_HOST'] != null ? process.env['MONGO_NODE_DRIVER_HOST'] : 'localhost';
var port = process.env['MONGO_NODE_DRIVER_PORT'] != null ? process.env['MONGO_NODE_DRIVER_PORT'] : Connection.DEFAULT_PORT;
// Require Underscore, if we're on the server, and it's not already present.
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('./underscore');
Database.ActiveRecord = function(attributes, collection){
this.collection = collection;
this.cid = _.uniqueId('c');
attributes || (attributes = {});
this.attributes = attributes;
};
// Connecting to database and setting the connection as a shared variable among ActiveRecords
console.log("Connecting to " + host + ":" + port);
Database.ActiveRecord.prototype.db = new Db('node-mongo-eslip', new Server(host, port, {}));
_.extend(Database.ActiveRecord.prototype, {
initialize: function(){},
// Returns `true` if the attribute contains a value that is not null
// or undefined.
has: function(attr) {
return this.attributes[attr] != null;
},
// Sets attributes
set: function(key, value){
var attrs, attr, val;
if(_.isObject(key) || key == null){
throw Error("The key should not be an object or null");
}else{
attrs = {};
attrs[key] = value;
}
if (!attrs) return this;
var now = this.attributes;
for(attr in attrs){
val = attrs[attr];
if(!_.isEqual(now[attr], val)) now[attr] = val;
}
},
unset: function(key){
return this.set(attr, null);
},
toJSON: function() {
return _.clone(this.attributes);
},
fetch: function(query, fields, options){
var record = this;
record.db.open(function(err, db){
if(!(record.collection||(typeof record.collection === 'string'))) throw Error('You should define a name attribute, which represents the collection of the Database');
db.collection(record.collection, function(err, collection){
console.log('Fetching...');
collection.find(query, fields, options).toArray(function(err, docs) {
return docs;
});
});
});
},
save: function(){
var record = this;
record.db.open(function(err, db){
if(!(record.collection||(typeof record.collection === 'string'))) throw Error('You should define a name attribute, which represents the collection of the Database');
db.collection(record.collection, function(err, collection){
collection.insert(_.clone(record.attributes), {safe:true},
function(err, objects) {
if (err) console.warn(err.message);
if (err && err.message.indexOf('E11000 ') !== -1) {
console.log('This id has already been inserted into the database');
}
});
});
console.log('Saved!');
});
}
});
}());
I’ve spend quite some time trying to figure out what is missing, and didn’t make it, maybe someone would have better odds of figuring out.
By the time the callback function from which you’re trying to run
return docsis being executed, the externalfetchfunction has already returned — as @SLaks suggested, welcome to the wonderful world of asynchronous programming.Promises can be an excellent way for dealing with asynchronous code — they’re available in jQuery, Dojo, and other libraries and toolkits. Your
fetchmethod could return a promise, and code that called thefetchmethod could react when the returned promise was “resolved”. Here’s what that looks like with Dojo:Then, code that called fetch might look like this: