user1966211
user1966211

Reputation: 873

Meteor cannot retrieve data from MongoDB

Pretty straightforward and without any sort of configuration ->

In the project directory I entered the command:

$ meteor mongo to access the mongodb

From there (mongo shell), I switched to db meteor using the command use meteor then entered some basic data to test:

j = { name: "mongo" }
k = { x: 3 }

db.testData.insert(j)
db.testData.insert(k)

I checked and got results by entering: db.testData.find()


Here's my meteor code provided that mongodb access is only required on the client:

if (Meteor.isClient) {
    Template.hello.greeting = function () {
        return "Welcome to test.";
    };

    Template.hello.events({
        'click input' : function () {
            // template data, if any, is available in 'this'
            if (typeof console !== 'undefined')
                console.log("You pressed the button");
        }
    });

    Documents = new Meteor.Collection('testData');

    var document = Documents.find();
    console.log(document);

    var documentCbResults = Documents.find(function(err, items) {
        console.log(err);
        console.log(items);
    });
}

Upon checking on the browser and based on the logs, it says undefined. I was unsuccessful from retrieving data from mongodb and showing to the client console.

What am I missing?

Upvotes: 1

Views: 1484

Answers (2)

David Weldon
David Weldon

Reputation: 64342

For this answer I'm going to assume this is a newly created project with autopublish still on.

As Christian pointed out, you need to define Documents on both the client and the server. You can easily accomplish this by just putting the collection definition at the top of the file or in another file which isn't in either of the server or client directories.

An example which prints the first two test documents could look like this:

Documents = new Meteor.Collection('testData');

if (Meteor.isClient) {
  Template.hello.greeting = function () {
    return "Welcome to apui.";
  };

  Template.hello.events({
    'click input' : function () {
      var documents = Documents.find().fetch();
      console.log(documents[0]);
      console.log(documents[1]);
    }
  });
}

Note the following:

  • The find function returns a cursor. This is often all you want when writing template code. However, in this case we need direct access to the documents to print them so I used fetch on the cursor. See the documentation for more details.
  • When you first start the client, the server will read the contents of the defined collections and sync all documents (if you have autopublish on) to the client's local minimongo database. I placed the find inside of the click event to hide that sync time. In your code, the find would have executed the instant the client started and the data probably would not have arrived in time.

Your method of inserting initial items into the database works (you don't need the use meteor by the way), however mongo will default to using an ObjectId instead of a string as the _id. There are subtle ways that this can be annoying in a meteor project, so my recommendation is to let meteor insert your data if at all possible. Here is some code that will ensure the testData collection has some documents:

if (Meteor.isServer) {
  Meteor.startup(function() {
    if (Documents.find().count() === 0) {
      console.log('inserting test data');
      Documents.insert({name: "mongo"});
      Documents.insert({x: 3});
    }
  });
}

Note this will only execute if the collection has no documents in it. If you ever want to clear out the collection you can do so via the mongo console. Alternatively you can drop the whole database with:

$ meteor reset

Upvotes: 1

Christian Fritz
Christian Fritz

Reputation: 21384

It's not enough to only define collections on the client side. Your mongo db lives on the server and your client needs to get its data from somewhere. It doesn't get it directly from mongodb (I think), but gets it via syncing with the collections on the server.

Just define the Documents collection in the joint scope of client and server. You may also need to wait for the subscription to Documents to complete before you can expect content. So safer is:

Meteor.subscribe('testData', function() {
    var document = Documents.find();
    console.log(document);
});

Upvotes: 0

Related Questions