Is this because MongoDB is not cached by the time I call find()?
If so is there some command to wait for MongoDB to get cached?
On following link I found an example of defining callback but it didn’t work for me
//DISPLAY DOCUMENTS.
for(i=0;i<playersArray.length;i++) {
var id = playersArray[i]._id;
var name = playersArray[i].name;
var score = playersArray[i].score;
console.log(id + ’ : ’ + name + ’ - ’ +score);
}
As soon as you subscribe to your meteor server publication it’ll return a handle with the following properties:
Meteor.subscribe returns a subscription handle, which is an object with the following properties:
stop()
Cancel the subscription. This will typically result in the server directing the client to remove the subscription’s data from the client’s cache.
ready()
True if the server has marked the subscription as ready. A reactive data source.
subscriptionId
The id of the subscription this handle is for. When you run Meteor.subscribe inside of Tracker.autorun, the handles you get will always have the same subscriptionId field. You can use this to deduplicate subscription handles if you are storing them in some data structure.
So you could use the ready() function to know when your collection is ready to display.
Imho you are doing it wrong. Meteor use a reactive programming model. You are not supposed to wait on callback. You declare relationship between data and templates with functions linking the two sides, and the function are rerun when the data is changing.
Your functions are meant to be idempotents, which means you can run then one or ten times and still get the same result (assuming parameters doesn’t change).
So you db access should be put either in an autorun (a code smell, imho…) or better in a template helper, which will be automatically rerun when data change (or is available).
You should take your code and enclose it in a Tracker autorun, starting after “if(Meteor.isClient){”, and it will probably work.
Now, add more documents in the console and your code will be rerun.
@hellstad
I am displaying them in JavaScript Console.
@rova
I am on autopublish currently so I don’t use subscribe.
If I were using subscription am I supposed to make infinite loop checking for ready() to return true?
Any example that could fit in my example?
@vjau
This example is not about templates.
Suppose I need to get some data from DB to make some calculations at some moment.
Like at the beginning while initializing the app.
Tracker autorun? What the hell is that? I’ll try to google?
Idempotents?
OK I have rewritten the code to use Tracker.autorun() and now the code will be executed the second time when collection is ready on the client. But the code doesn’t look clean. Is there some other way to say "Wait for collections to get cached before executing “if (Meteor.isClient) {}”
//CREATE LOCAL AND REMOTE COLLECTIONS.
people = new Mongo.Collection('people');
//SERVER.
if (Meteor.isServer) {
//INSERT DOCUMENTS.
if( people.find().count() == 0 ) {
people.insert({ name : "John", age : 20 });
people.insert({ name : "Bill", age : 30 });
people.insert({ name : "Lucy", age : 40 });
}
}
//CLIENT.
if (Meteor.isClient) {
console.log("Template.subscriptionsReady="+Template.subscriptionsReady);
//UPDATE PERSON.
Tracker.autorun(function () {
person = people.findOne( {name : "John"} );
if(person) {
people.update( person._id, {$set : {age: 60}} )
};
});
//BODY HELPERS.
Template.body.helpers({
people: function() {
return people.find();
}
});
}
I am trying to make little tutorial/example which demonstrates how do you update record in Meteor. And in order to update a record I need to have one already inside DB. And since I want examples to be as simple as possible I dislike having to use Tracker.autorun() in a tutorials which is supposed to focus on updating record. Since I wasn’t able to find elegant way of demonstrating DB commands on client side I have rewritten all of the tutorials by using the commands on the server side where this problem doesn’t occur.
//CREATE LOCAL AND REMOTE COLLECTIONS.
people = new Mongo.Collection('people');
//SERVER.
if (Meteor.isServer) {
//CLEAR COLLECTION.
people.remove({});
//INSERT DOCUMENTS.
people.insert({ name : "John", age : 20 });
people.insert({ name : "Bill", age : 30 });
people.insert({ name : "Lucy", age : 40 });
//RETRIEVE DOCUMENT.
person = people.findOne( {name : "John"} );
//UPDATE DOCUMENT.
people.update( person._id, {$set : {age: 70}} )
//RETRIEVE DOCUMENTS.
peopleCursor = people.find();
//DISPLAY DOCUMENTS.
peopleCursor.forEach(function(person){
var id = person._id;
var name = person.name;
var age = person.age;
console.log(id + ' : ' + name + ' - ' + age);
});
}