Reputation: 103
I originally thought my collection wasn't receiving data, but it turns out I just had a typo in my query. But my data still isn't appearing on the screen. The HTML template is pretty basic, here it is:
<template name="messages" class=".messages">
{{#each showMessages}}
<blockquote>
<p>{{message}}</p>
</blockquote>
{{/each}}
</template>
It's supposed to just make the collection of messages appear when I call {{> messages}} Here's the client side JS that corresponds to it:
Meteor.subscribe("Messages");
Template.messages.helpers({
showMessages: function(){
return Meteor.call("find");
}
});
and here's the server method:
Meteor.methods({
insert:function(username, message){
var id = Messages.insert({
'message': message,
'user': Meteor.userId(),
'username': username,
'timestamp': new Date()
});
return "success";
},
'find': function(){
return Messages.find({},{sort:{timestamp:-1}}, 20).fetch();
}
});
I'm pretty new to MeteorJS, I just picked it up yesterday, so it's probably something really basic that I am missing, but I've been slamming my head against this for 2 hours and have made 0 progress. I don't have insecure or autopublish enabled. This isn't meant to be a usable product or anything, I'm using this to teach myself, so I know that I am doing some insecure things.
Upvotes: 3
Views: 534
Reputation: 1367
I have prepared some MeteorPad for those starting questions. You may find some first instructions here
http://meteorpad.com/pad/Ba5DTe94NjFi3ZTPA/Playground_Flow-Router_Chat
Good luck Tom
Upvotes: 0
Reputation: 36900
In this case, it's mostly about a misunderstanding of Meteor's data model.
Although it's possible to send data using a method call, usually you'll want to use publications and subscriptions to send data to the client. These have the almost magical property that queries are live - that is, any updates to the query will be sent to the client automatically. The current code you have, if it worked properly, wouldn't have live data. The specific issue is that Meteor.call
is asynchronous, so your messages helper won't be seeing anything.
Instead, here's what you want to do. On the server, you will set up a publication of the messages collection:
Meteor.publish("someWeirdName", function() {
return Messages.find({},{ sort: { timestamp:-1}, limit: 20});
});
Note the differences from your code: there is no fetch()
, because we want a live cursor, and the 20
is probably what you intended as a limit option. Note that I also called this someWeirdName
because that is the name of the publication, and not the collection, which you will use to subscribe on the client. For a more detailed explanation, you may want to see this post.
Then, on the client, you simply need the following:
Meteor.subscribe("someWeirdName");
Template.messages.helpers({
showMessages: function(){
return Messages.find();
}
});
Note that your previous call of Meteor.subscribe("Messages")
was doing nothing, because there was no publication named Messages
. Also, we're going to use the client side cache of messages to create a cursor to display the messages.
Also, all of this code requires that you have the following declared on both the server and the client:
Messages = new Mongo.Collection("callMeWhateverYouWant");
Note also that the argument used to instantiate this collection has nothing to do with how you refer to the collection in your code, unless you are writing a custom publication. It simply identifies the collection in the underlying database.
Upvotes: 2
Reputation: 4948
Calling a method is async, so returning the result in the helper won't do any good. Similarly, fetch isn't reactive.
showMessages: function(){
return Messages.find({},{sort:{timestamp:-1}, limit: 20});
}
Go ahead & read discover meteor before making your own project. I'm all for struggling to teach yourself something new, but a nice solid foundation will work wonders & eliminate a lot of frustration.
Upvotes: 0