Reputation: 1007
On my local host, I have the following Node code to setup a mongoDB database name "dbname":
users.js:
var MongoClient = require("mongodb").MongoClient,
Connection = require("mongodb").Connection,
Server = require("mongodb").Server;
Users = function(host, port) {
var mongoClient = new MongoClient(new Server(host, port));
mongoClient.open(function (){});
this.db = mongoClient.db("dbname");
};
Users.prototype.getCollection = function (callback) {
this.db.collection("users", function (error, users) {
if (error) callback(error);
else callback(null, users);
});
};
Users.prototype.findAll = function (callback) {
this.getCollection(function (error, users) {
if (error) {
callback(error);
} else {
users.find().toArray(function (error, results) {
if (error) {
callback(error);
} else {
callback(null,results);
}
});
}
});
}
// Bunch of other prototype functions...
exports.Users = Users;
I like to put the above database functionality in one file, and then in my main server file require that file as follows:
server.js:
var Users = require("./users").Users;
var users = new Users("localhost", 27017);
users.findAll(function (err, user) {
// Do something
});
To have this working on localhost is pretty easy. In the command line, I just type the following:
$ mongod # to launch the database server
$ node server.js # to launch the web server
and it works fine. However, now I'm trying to push the whole thing onto Heroku with the mongolab addon
heroku addons:add mongolab
but the database is not running and I have no idea how to make it run. This tutorial explains how to setup mongodb with the mongolab URI, but that's not how my code works, I use a host and a port and I create a new server based on that. How should I change my code for it to work on the heroku app? I want to keep the database code in a separate file, with the prototype functions.
Upvotes: 1
Views: 3736
Reputation: 1007
Helped by Xinzz's answer, here's the modified code, so that the mongodb database is initialized with a URI instead of host + port. That's how Heroku initializes the mongodb database, and that's why it wasn't working.
var mongodb = require("mongodb");
var MONGODB_URI = process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || "mongodb://localhost", // Make sure to replace that URI with the one provided by MongoLab
db,
users;
mongodb.MongoClient.connect(MONGODB_URI, function (err, database) {
if (err) throw err;
db = database;
users = db.collection("users");
accounts = db.collection("accounts");
var server = app.listen(process.env.PORT || 3000);
console.log("Express server started on port %s", server.address().port);
});
The key here is to declare the variables db and users upfront, assign them a value in the asynchronous callback of the connect function of MongoClient and also start the app (app.listen(...)
) in the same callback. Then later in the code I can do the following:
users.find().toArray(function (err, results) {
// Do something
});
I also gave up on all these prototype functions, since they did not really add much.
Upvotes: 1
Reputation: 2252
Follow the example here at the "MongoClient.connect" section.
Essentially, you will need to change this part of the code:
Users = function(host, port) {
var mongoClient = new MongoClient(new Server(host, port));
mongoClient.open(function (){});
this.db = mongoClient.db("dbname");
};
To use mongoClient.connect() instead of new MongoClient:
Users = function(url) {
MongoClient.connect(url, function(err, db) {
// Find better way to set this since this callback is asynchronous.
this.db = db;
});
};
If you are using node, I recommend using a library such as mongoose npm install mongoose
to handle mongodb interactions. Look at my answer here for how to structure your schemas.
Upvotes: 2