Should I use methods, publish/subscribe, helpers?


#1

Hi, just started learning Meteor. I need data for the currently logged user. In Mongo terms, the query would look like this:

myCollections.find({ 
        "$or": [ 
          {"owner": Meteor.userId()}, 
          {"isPublic": true} 
        ] 
      });

assuming a user is logged in of course.

Now I’m really confused as to which of methods, publish/subscribes and helpers I should use and when. As for helpers, they’ll be bound to some template obviously so they’re not the best for queries that will be made from different places. Are there any kind of best practices on this topic? Any general advice?

Thank you!


#2
Publish and Subscribe

There basically there to for the exchange of data between your Mongo server, and your client. So you’d have to use them first, in order to get the data between the two. In your case, it would mean that on the server, you’d have something like that :

Meteor.publish("nameOfPublication", function() {
    return myCollections.find({ 
        "$or": [ 
          {"owner": Meteor.userId()}, 
          {"isPublic": true} 
        ] 
      });
})

And on the client, depending on if you’re using a router or not, you’d have to subscribe on the template you want this data like this either inside the onCreated or directly on the route:

Meteor.subscribe("nameOfPublication");

After that, you’ll have your data client side, and you can then use helpers to use them inside your template:

Template.myTemplate.helpers({
    myDate: function(){
        return myCollection.find({}); // whatever query you need for the users
    }
})

Which would give you access to the data on the template with {{myData}} for example.

Now if you haven’t done it, you shoud complete this tutorial : Meteor Getting Started. Because there’s multiple things you have to learn like the autopublish and unsecure package that are there in every app created with Meteor. After you’ve completed this tutorial, there’s many courses you could take like DiscoverMeteor and more advance one like BulletProof Meteor

As for Methods, they are simply function that will only be executed server side. You can use them for example to insert new data in your database when you have to make sure some of the field are in a specific form and you don’t the user to be able to do what he wants with it…


#3

Usually you call methods from within your helpers which in turn are ‘referenced’ from your templates. The reason you do it that way and not subscribe directly to collections from within a helper is primary security.

Speaking of, sooner or later you’ll end up writing allow/deny rules on your collections, there’s a package wrapping those with a nice API https://github.com/ongoworks/meteor-security/


#4

Not quite, first they execute on the client against minimongo, then, some time later after a roundtrip to the server and having executed the same method there, the result comes back and it’s either in-line with what the client-side method came up with or not… in which case the server-side result is taken to be the result that finally wins. Optimistic UI that is :slight_smile:


#5

You’re right, i was focusing on the server control on those type of function, which made me say that wrong explanation. Thanks for pointing that out :wink:


#6

No worries, I usually refrain from being smartassish, it’s just so that I think understanding, and from time to time remembering, the concept of an optimistic UI is something that’s one of the main unique selling propositions of meteor and therefore always worth pointing out.


#7

Thank you shad and markusgattol! It all makes much more sense now.

I’ve gone through the “Getting Started” tutorial but it’s a lot of info that needs to sink in and the way you explain it is much clearer IMHO. Meteor uses a language I’m not 100% comfortable with yet and in a framework that’s very different than what I’m used to (I’m a PHP developer, used to CodeIgniter and Symfony).


#8

No worries :wink:

I’ve just realized something. You were proposing a mongo query with $or which is from the aggregation modules in MongoDB and it’s not yet a supported reactive data inside meteor. It’s basically means that meteor won’t update in real time your data if you’re using it (except if you’re including an community made package to make it possible, and on this point, you can find lots of amazing package for meteor over at atmosphere if you don’t now it yet…).


#9

Oh! Thank you for the heads-up, that would’ve been another big headache, trying to find out why my simple query did not work… I’ll look for an atmosphere package that does the job.


#10

Oh, and I just checked to make sure and $or is both a regular logical operator and an operator of the aggregation framework so it can be used in both contexts, unless there are some Meteor-specific limitations I’m not aware of.

Logical $or
Aggregate $or


#11

publications/subscriptions basically decide what will be loaded into minimongo on the client. For example, try making a publication like this:

Meteor.publish('cats', function (limit) {
  var limit = limit || 10;
  return Cats.find({}, { limit: limit });
});

You can try publishing and subscribing and seeing what happens on the client

Meteor.subscribe('cats', 20);
Cats.find().count()   // result: 20
Meteor.subscribe('cats', 50);
Cats.find().count()   // result: 50

#12

Good find, i had forgot about those. I should not be a problem in the case of the first one then :wink:


#13

Ah! thanks, I almost forgot to include a limit into my publications. runs off to edit some collections