How do I setup MongoDB database on Heroku with MongoLab?
Asked Answered
I

1

7

I'm using Express.js and MongoLab and I followed the Heroku setup to get MongoDB working in production throwing this code in my app.js.

//Mongo on Heroku Setup
var mongo = require('mongodb');

var mongoUri = process.env.MONGOLAB_URI || 
  process.env.MONGOHQ_URL || 
  'mongodb://localhost/mydb'; 

mongo.Db.connect(mongoUri, function (err, db) {
  db.collection('mydocs', function(er, collection) {
    collection.insert({'mykey': 'myvalue'}, {safe: true}, function(er,rs) {
    });
  });
});

and I have the following routes and field for my email form (also in app.js):

//Routes

app.get('/', function(req, res) {
    res.render('index', {
        title: 'DumbyApp'
    });
});

//save new email
app.post('/', function(req, res){
    emailProvider.save({
        address: req.param('address')
    }, function( error, docs) {
        res.redirect('/')
    });
});

This renders the new form on the index page and lets me save it locally but not in production because I don't know how to setup my email collection. Can anyone walk me through this? brand new to using MongoDB and Node.js, so could use some help.

EDIT:

In The MongoLab Database Interface, I made a collection called emails. Is this the right course of action?

EDIT 2:

Here's defining EmailProvider in app.js along with the file itself.

app.js

 var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path')
  , EmailProvider = require('./emailprovider').EmailProvider;

var emailProvider= new EmailProvider('localhost', 27017);

emailprovider.js

var Db = require('mongodb').Db;
var Connection = require('mongodb').Connection;
var Server = require('mongodb').Server;
var BSON = require('mongodb').BSON;
var ObjectID = require('mongodb').ObjectID;

EmailProvider = function(host, port) {
  this.db= new Db('localdb', new Server(host, port, {safe: false}, {auto_reconnect: true}, {}));
  this.db.open(function(){});
};


EmailProvider.prototype.getCollection= function(callback) {
  this.db.collection('emails', function(error, email_collection) {
    if( error ) callback(error);
    else callback(null, email_collection);
  });
};

//save new email
EmailProvider.prototype.save = function(emails, callback) {
    this.getCollection(function(error, email_collection) {
      if( error ) callback(error)
      else {
        if( typeof(emails.address)=="undefined")
          emails = [emails];

        for( var i =0;i< emails.address;i++ ) {
          email = emails[i];
          email.created_at = new Date();
        }

        email_collection.insert(emails, function() {
          callback(null, emails);
        });
      }
    });
};

exports.EmailProvider = EmailProvider;
Irredentist answered 21/5, 2013 at 0:57 Comment(6)
Hi! There seems to be some context missing. Your MongoDB connection code looks fine, but what's the definition of emailProvider?Lithoid
@Lithoid OK, I edited to make it more understandable of what's going on.Irredentist
Am I reading correctly that your EmailProvider is connecting to localhost:27017? Are you trying to connect it to your MongoLab database instead?Lithoid
@Lithoid Yes, I want to connect it to MongoLab or on Heroku.Irredentist
Ok, well the code as shown is connecting to a database at localhost:27017/localdb and all that setup in your first code block is being ignored. I would start by changing the EmailProvider constructor to take a URI instead of host and port and move the correct connection logic you're showing in the first code block into there. Then, in app.js, pass the MONGOLAB_URI to the constructor instead of 'localhost' and 27017.Lithoid
The link (devcenter.heroku.com/articles/nodejs#using-mongodb) no longer works. The new page is elements.heroku.com/addons/#data-storesPedant
L
6

While the connection code in the first code box appears to be correct, the emailProvider object isn't using it. Instead, in app.js, the EmailProvider is being connected to localhost:27017 and the database name is hardcoded in emailprovider.js as 'localdb'.

What you want to do instead is use the connection information provided in the MONGOLAB_URI environment variable in your EmailProvider, which contains the host, port, and database name already.

There are a number of ways to go about doing this, but one way would be to move your connection code from that first code box into the EmailProvider constructor, and then change the constructor so that it takes a URI instead of a host and port. That way, you can pass the MONGOLAB_URI variable to the constructor in app.js.

Lithoid answered 21/5, 2013 at 3:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.