I have found many blog posts, guides and tutorials displaying the shiny new thing called Meteor. In all it’s glory. Those little nasty things hidden beneath aren’t discussed in detail or are simply left out. Don’t get me wrong I’m a huge fan of Meteor. But after struggling (again) for many days, I decided to begin this little list of things that I have learned, that aren’t so nice or have to be kept in mind. Plus a strategy how to deal with those cases. The word anti-patterns comes to my mind, but it doesn’t really fit.
In this first post I will talk about Meteor’s Collections. In later posts I will discuss further aspects. Template’s is another big area of confusion and will be discussed next. As the need arises and my understanding deepens I will update this and the latter posts accordingly.
Dealing with Meteor Collections
Collections are pretty complex things. They aren’t serializable to EJSON. No transport across the wire. But why would anyone want to do such a stupid thing, anyway? Well. I did. When starting off with Meteor I was thinking: ‘Damn, I have defined this Collection at the client (server) how do I make it available on the server (client)’. Stupid me, right? Until recently, I found out, that this is not an uncommon question.
First of all, this is simpler than you think. Defining a collection this way:
MyCollection = new Meteor.Collection ‘mine’
is really sufficient in most cases. But put this line in a file which is executed on the server AND the client.
Beware to call:
new Meteor.Collection ‘name’
more than once for every string identifier (‘name’ in this case). Meteor will throw errors. Meaningful one’s this time.
To make the collection accessible from other files you simple prepend the @ sign (in CoffeeScript). When you are writing package code, don’t use the @ sign, instead export the Collection in package.js, e.g.:
That make it visible in your app code and the other files in your package.
Dealing With Dynamic Collections
Meaning, you are creating Collections on the fly. You usually don’t need this, but in case.
You can’t store them in the Session object. That results in weird behaviour. I accidently did this, as I tried to store an object that itself held a reference to a Collection. Weird behaviour and no decipherable error messages, sadly.
Simply use a hash or a plain object to hold the reference to the collection.
Of course you can not store a Collection in another Collection. You might store the id of a document that you are referencing as well as the name of the Collection where the document belongs in another Collection. And instantiate the Collection object as well as find and read the referenced document as needed. Like so:
Loading Initial Data
If you try to load initial data (fixtures) on the client, you might end up with two (or more) documents in the collection. I don’t actually understand why this is the case. But that’s the way it is. The following code won’t work!
Wrapping the creation part in Meteor.startup () -> doesn’t help either. With the second page load you get a second document. That sucks, right?
You can create the initial documents on the server. I guess that’s the preferred way to do this.
Nevertheless you can do it on the client, as well, but you need to leverage Meteor’s pub/sub mechanism to achieve the desired result. The following gist works and survives reloads.
Pub / Sub
We have touched Meteor’s publish / subscribe mechanism earlier and I won’t go very deep in all the possibilities Meteor offers. Just one thing to keep in mind: subscriptions provide a partial view of the documents stored in the published collections. For example (like shown above) you can narrow down the number of documents published in a given subscription to exactly one by selecting the documents by their _id property.
For an in-depth discussion you should check out Discover Meteor‘s chapters dealing with pub/sub.