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;
Jryl
  • 1,156
  • 4
  • 11
  • 20
  • 1
    Hi! There seems to be some context missing. Your MongoDB connection code looks fine, but what's the definition of emailProvider? – robert May 21 '13 at 01:20
  • @robert OK, I edited to make it more understandable of what's going on. – Jryl May 21 '13 at 01:42
  • 1
    Am I reading correctly that your EmailProvider is connecting to localhost:27017? Are you trying to connect it to your MongoLab database instead? – robert May 21 '13 at 02:04
  • @robert Yes, I want to connect it to MongoLab or on Heroku. – Jryl May 21 '13 at 02:10
  • 1
    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. – robert May 21 '13 at 02:32
  • The link (https://devcenter.heroku.com/articles/nodejs#using-mongodb) no longer works. The new page is https://elements.heroku.com/addons/#data-stores – Ryan Feb 12 '16 at 04:10

1 Answers1

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.

robert
  • 316
  • 1
  • 4