Reputation: 26034
I am trying to connect to my Mongo database which is situated on the machine as my Meteor app. Here are two files in my app:
a.js:
if (Meteor.isServer) {
var database = new MongoInternals.RemoteCollectionDriver("mongodb://127.0.0.1:3001/meteor");
Boxes = new Mongo.Collection("boxes", { _driver: database });
Meteor.publish('boxes', function() {
return Boxes.find();
});
}
b.js:
if (Meteor.isClient) {
Meteor.subscribe('boxes');
Template.homeCanvasTpl.helpers({
boxes: function () {
return Boxes.find({});
}
});
}
But I keep getting a "Exception in template helper: ReferenceError: Boxes is not defined" error - any ideas?
Upvotes: 6
Views: 15382
Reputation: 1279
How can you connect to a MongoDB with Meteor?
Scenario A: Use the built-in DB as default
This is much simpler than what you did. When you run meteor
you actually start a DB with the Meteor server, where Meteor listens on port 3000 and the database on port 3001. The Meteor app is already connected to this database at port 3001 and uses a db named meteor
. There is no need whatsoever to fall back to MongoInternals.RemoteCollectionDriver
. Just remove that code and change things to:
Boxes = new Mongo.Collection("boxes"); // use default MongoDB connection
Scenario B: Use a different DB as default
Using the MONGO_URL
environment variable you can set the connection string to a MongoDB when starting the Meteor server. Instead of the local port 3001 database or an unauthenticated connection you can specify exactly where and how to connect. Start your Meteor server like this:
$ MONGO_URL=mongodb://user:password@localhost:27017/meteor meteor
You can also leave out the user:password@
part of the command if no authentication is needed.
Scenario C: Connect to a second (3rd, etc) DB from the same Meteor app
Now we need to use MongoInternals.RemoteCollectionDriver
. If you wish to use another database that is not the default DB defined upon starting the Meteor server you should use your approach.
var database = new MongoInternals.RemoteCollectionDriver('mongodb://user:password@localhost:27017/meteor');
var numberOfDocs = database.open('boxes').find().count();
Bonus: Why should you not use MongoInternals
with Mongo.Collection
?
As the docs indicate you should not pass any Mongo connection to the new Mongo.Collection()
command, but only a connection to another Meteor instance. That means, if you use DDP.connect
to connect to a different server you can use your code - but you shouldn't mix the MongoInternals
with Mongo.Collection
- they don't work well together.
Upvotes: 19
Reputation: 26034
Based on feedback from saimeunt in the comments above, s/he pointed out that MongoInternals is unavailable to the client portion of a Meteor app. Therefore, the solution was to add in the line "Boxes = new Mongo.Collection("boxes");" to the client logic - here was the final working solution:
a.js:
if (Meteor.isServer) {
var database = new MongoInternals.RemoteCollectionDriver("mongodb://127.0.0.1:3001/meteor");
Boxes = new Mongo.Collection("boxes", { _driver: database });
Meteor.publish('boxes', function() {
return Boxes.find();
});
}
b.js
if (Meteor.isClient) {
Boxes = new Mongo.Collection("boxes");
Meteor.subscribe('boxes');
Template.homeCanvasTpl.helpers({
boxes: function () {
return Boxes.find({});
}
});
}
Upvotes: 1
Reputation: 22696
Meteor has 2 different environment : the server environment running on Node.JS and the client environment running in browsers.
In your code you declare the Boxes
Mongo collection only in the server environment, you need to take this declaration out of the Meteor.isServer
condition (and BTW don't use these, separate your code in server/
, client/
and lib/
directories).
Also, not sure if you need to connect to your MongoDB this way, maybe you should look into the MONGO_URL
environment variable it probably already does what you need ? (provide a mongo connection URL to a distant (or local) Mongo server).
Upvotes: 0