{"action":"created","comment":{"url":"https://api.github.com/repos/meteor/guide/pulls/comments/45576821","id":45576821,"diff_hunk":"@@ -0,0 +1,556 @@\n+---\n+title: Data Loading and Management\n+---\n+\n+After reading this guide, you'll know:\n+\n+1. What publications and subscriptions are in the Meteor framework\n+2. How to define a publication on the server\n+3. Where to subscribe on the client and in which template\n+4. Useful patterns to follow to subscribe sensibly and help users understand the state of subscriptions.\n+5. How to create publish sets of related data in a reactive way.\n+6. How to ensure your publication is properly authorized in a reactive way.\n+7. How to use the low-level publish API to publish anything.\n+8. How to turn a 3rd-party REST endpoint into a publication.\n+9. How to turn a publication into your app into a REST endpoint.\n+\n+## Publications and Subscriptions\n+\n+Unlike in Meteor, a traditional web application communicates between client and server in a \"request-response\" fashion. Typically the client makes RESTful HTTP requests to the server and receives data (either in pre-rendered HTML, or perhaps some on-the-wire data format) in response. However there's no way for the server to \"push\" data to the client when changes happen at the backend.\n+\n+Meteor however is built from the ground up on the Distributed Data Protocol (DDP) to allow data transfer in both directions. So (although you can), building a Meteor app doesn't require fashion REST endpoints to serialize and send data. Instead you create *publication* endpoints to push data from server to client.\n+\n+In Meteor a **publication** is a named API on the server that constructs a set of data to send to a client. A client creates a **subscription** which connects to a publication, and receives that data. That set of data consists of an initial stream of data as it stands at subscription-time, and then,over time a set of updates as that data set changes. \n+\n+So a subscription is a set of data that changes over time. Typically, the net result of this is that a subscription \"bridges\" a server collection (which as described in the \"Collections\" article, corresponds closely with a Mongo collection), and the client side Minimongo cache of that data. You can think of a subscription a pipe that connects a subset of the true collection with the clients version, but that constantly keeps it up to date with the latest information on the server.\n+\n+## Defining a publication\n+\n+A publication should be defined in a server-only file. For instance, in the Todos example app, we want to publish the set of public lists to all users:\n+\n+```js\n+Meteor.publish('lists/public', function() {\n+  return Lists.find({userId: {$exists: false}});\n+});\n+```\n+\n+There are a few things to understand about this code block. Firstly, we've named the publication `lists/public`, and that will be how we access it from the client. Secondly, we are simply returning a Mongo *cursor* from the publication function.\n+\n+What that means is that the publication will simply ensure the set of data matching that query is available to any client that subscribes to it. In this case, all lists that do not have a `userId` setting. So the collection named `'Lists'` on the client (which we called `Lists` of course) will have all of the public lists that are available in the server collection named `'Lists'` whilst that subscription is open (which is all the time in our example app).\n+\n+There are two types of parameters of a publish function. Firstly, a publication always has the current user's `id` available at `this.userId` (this is why we use the `function() {}` form for publications rather than the ecmascript `() => {}`. You can disable the linting rule for publication files with `eslint-disable prefer-arrow-callback`).\n+\n+```js\n+Meteor.publish('lists/private', function() {\n+  if (!this.userId) {\n+    return this.ready();\n+  }\n+\n+  return Lists.find({userId: this.userId});\n+});\n+```\n+\n+What this means is that the above publication can be confident (thanks to Meteor's accounts system) that it will only ever publish private lists to the user that they belong to. Note also that the publication will re-run if the user logs out (or back in again), which means that the published set of private lists will reflect this.\n+\n+In the case of a non-logged in user, we explicitly call `this.ready()`, which indicates to the subscription that we've sent all the data we are initially going to send (in this case none).\n+\n+The other type of publication argument is a simple named argument:\n+\n+```js\n+Meteor.publish('list/todos', function(listId) {\n+  check(listId, String);\n+\n+  ...\n+});\n+```\n+\n+When we create a subscription to this piblication on the client, we can provide this argument via the `Meteor.subscribe()` call:\n+\n+```js\n+Meteor.subscribe('list/todos', list._id);\n+```\n+\n+Also note that we are careful to check the `listId` is a string as we expect, as described in the Security article.\n+\n+### Organizing Publications\n+\n+It makes sense to place a publication in a package alongside the feature that it's targeted. For instance, sometimes publications provide very specific data that's only really useful for the view that they are developed for. In that case, placing the publication in the same package as the view code makes perfect sense.\n+\n+Often, however, a publication is more general. For example in the Todos example application, we create a `list/todos` publication, which publishes all the todos in a list. Although in the application we only use this in one place (in the `listsShow` template), in a larger app, there's a good chance we might need to access all the todos for a list in other places. So putting the publication in the `todos` package is a sensible approach.\n+\n+## Using publications: Subscriptions\n+\n+To use publications, you need to create a subscription to it on the client. To do so, you call `Meteor.subscribe()` with the name of the publication. When you do this, it opens up a subscription to that publication, and the server starts sending data down the wire to ensure that your client collections contain up to date copies of the data that's pushed by the publication.\n+\n+### Organizing Subscriptions\n+\n+It is best to place the subscription as close as possible to the place where the data from the subscription is needed. This reduces \"action at a distance\" and makes it easier to understand the flow of data through your application.\n+\n+What this means in practice is that you should place your subscription calls in *templates*. In Blaze, it's best to do this in the `onCreated()` callback:\n+\n+```js\n+Template.listsShowPage.onCreated(function() {\n+  this.state = new ReactiveDict();\n+  this.autorun(() => {\n+    this.state.set('listId', FlowRouter.getParam('_id'));\n+    this.subscribe('list/todos', this.state.get('listId'));\n+  });\n+});\n+```\n+\n+In this code snippet we can see two important techniques for subscribing in Blaze templates:\n+\n+1. Calling `this.subscribe()` (rather than `Meteor.subscribe`) means that the subscription will automatically get torn down when the template is taken off the screen.\n+\n+2. Calling `this.autorun` sets up a reactive context which will re-initialize the subscription whenever the reactive variable `this.state.get('listId')` changes.\n+\n+### Fetching subscription data\n+\n+Once you've subscribed to a set of data, you then need to query the client collections to fetch the data again. There are a few important rules of thumb when doing this.\n+\n+1. Always use the same query to fetch the data from the collection that you use to publish it. \n+\n+  If you don't do this, then you open yourself up to problem if another subscription pushes data into the same collection. Although you may be confident that this is not the case, in an actively developed application, it's impossible to anticipate what may change in the future and this can be a source of hard to understand bugs.\n+\n+  Also, when changing subscriptions, there is a brief period where both subscriptions are loaded (see \"Publication behaviour when changing arguments\" below), so when doing thing like pagination, it's exceedingly likely that this will be the case.\n+\n+2. Fetch the data as close as possible to where you subscribe to it.\n+\n+  We do this for the same reason we subscribe in the template in the first place -- to avoid action at a distance and to make it easier to understand where data comes from. A common pattern is to fetch the data in a parent template, and then pass it into a \"pure\" child template, as we'll see in in the {% post_link ui-ux \"UI/UX Article\"%}.\n+\n+  Note that there are some exceptions to this second rule. A common one is `Meteor.user()`---although this is strictly speaking subscribed to (automatically usually), it's typically over-complicated to pass it through the template heirarchy as an argument to each template (although you could do this if you want to be \"pure\" about everything). \n+\n+  A second exception is sometimes in Blaze when you want to be more performant by controlling re-renderings. As an example in the Todos example application, although we subscribe to the `lists/todos` publication in the `listShowPage`, we don't actually fetch the todos further down the template heirarchy, in order to avoid the todos rendering too much when properties of the list change.","path":"content/data-loading.md","position":123,"original_position":123,"commit_id":"398878f1a3d4b1d7943e9c9b22fec82af9957928","original_commit_id":"398878f1a3d4b1d7943e9c9b22fec82af9957928","user":{"login":"stubailo","id":448783,"avatar_url":"https://avatars.githubusercontent.com/u/448783?v=3","gravatar_id":"","url":"https://api.github.com/users/stubailo","html_url":"https://github.com/stubailo","followers_url":"https://api.github.com/users/stubailo/followers","following_url":"https://api.github.com/users/stubailo/following{/other_user}","gists_url":"https://api.github.com/users/stubailo/gists{/gist_id}","starred_url":"https://api.github.com/users/stubailo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stubailo/subscriptions","organizations_url":"https://api.github.com/users/stubailo/orgs","repos_url":"https://api.github.com/users/stubailo/repos","events_url":"https://api.github.com/users/stubailo/events{/privacy}","received_events_url":"https://api.github.com/users/stubailo/received_events","type":"User","site_admin":false},"body":"Should we change this? I don't think there is actually any performance benefit to fetching down the tree, since we can just pass the cursor through.","created_at":"2015-11-23T07:28:27Z","updated_at":"2015-11-23T07:28:27Z","html_url":"https://github.com/meteor/guide/pull/97#discussion_r45576821","pull_request_url":"https://api.github.com/repos/meteor/guide/pulls/97","_links":{"self":{"href":"https://api.github.com/repos/meteor/guide/pulls/comments/45576821"},"html":{"href":"https://github.com/meteor/guide/pull/97#discussion_r45576821"},"pull_request":{"href":"https://api.github.com/repos/meteor/guide/pulls/97"}}},"pull_request":{"url":"https://api.github.com/repos/meteor/guide/pulls/97","id":51043500,"html_url":"https://github.com/meteor/guide/pull/97","diff_url":"https://github.com/meteor/guide/pull/97.diff","patch_url":"https://github.com/meteor/guide/pull/97.patch","issue_url":"https://api.github.com/repos/meteor/guide/issues/97","number":97,"state":"open","locked":false,"title":"Data loading content","user":{"login":"tmeasday","id":132554,"avatar_url":"https://avatars.githubusercontent.com/u/132554?v=3","gravatar_id":"","url":"https://api.github.com/users/tmeasday","html_url":"https://github.com/tmeasday","followers_url":"https://api.github.com/users/tmeasday/followers","following_url":"https://api.github.com/users/tmeasday/following{/other_user}","gists_url":"https://api.github.com/users/tmeasday/gists{/gist_id}","starred_url":"https://api.github.com/users/tmeasday/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tmeasday/subscriptions","organizations_url":"https://api.github.com/users/tmeasday/orgs","repos_url":"https://api.github.com/users/tmeasday/repos","events_url":"https://api.github.com/users/tmeasday/events{/privacy}","received_events_url":"https://api.github.com/users/tmeasday/received_events","type":"User","site_admin":false},"body":"<a href='#crh-start'></a><a href='#crh-data-%7B%22processed%22%3A%20%5B%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576527%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576543%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576576%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576626%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576641%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576682%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576714%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576733%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576734%22%2C%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576786%22%5D%2C%20%22comments%22%3A%20%7B%22Pull%20398878f1a3d4b1d7943e9c9b22fec82af9957928%20content/data-loading.md%20121%22%3A%20%7B%22html_url%22%3A%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576786%22%2C%20%22comments%22%3A%20%5B%7B%22body%22%3A%20%22Although%20you%20don%27t%20want%20to%20pass%20it%20through%20as%20an%20argument%20everywhere%2C%20I%27d%20still%20recommend%20being%20judicious%20with%20where%20you%20use%20it%2C%20since%20it%20could%20make%20your%20components%20more%20annoying%20to%20test.%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A27%3A28Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/448783%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/stubailo%22%7D%7D%5D%2C%20%22title%22%3A%20%22File%3A%20content/data-loading.md%3AL1-557%22%7D%2C%20%22Pull%20398878f1a3d4b1d7943e9c9b22fec82af9957928%20content/data-loading.md%20103%22%3A%20%7B%22html_url%22%3A%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576682%22%2C%20%22comments%22%3A%20%5B%7B%22body%22%3A%20%22Actually%2C%20Meteor.subscribe%20would%20also%20tear%20down%20the%20subscription%20because%20of%20how%20autorun%20works%2C%20but%20the%20real%20benefit%20is%20being%20able%20to%20use%20%60Template.instance%28%29.subscriptionsReady%28%29%60.%20%28This%20was%20designed%20to%20replace%20%60waitOn%60%20in%20Iron%20Router%20%3A%5D%20%29%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A24%3A46Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/448783%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/stubailo%22%7D%7D%2C%20%7B%22body%22%3A%20%22Oh%20right%2C%20%3Ablush%3A%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A26%3A06Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/132554%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/tmeasday%22%7D%7D%5D%2C%20%22title%22%3A%20%22File%3A%20content/data-loading.md%3AL1-557%22%7D%2C%20%22Pull%20398878f1a3d4b1d7943e9c9b22fec82af9957928%20content/data-loading.md%20109%22%3A%20%7B%22html_url%22%3A%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576714%22%2C%20%22comments%22%3A%20%5B%7B%22body%22%3A%20%22%5C%22Subscribing%20to%20data%20puts%20it%20in%20your%20client-side%20collections.%20To%20use%20the%20data%20in%20your%20templates%2C%20you%20need%20to%20query...%5C%22%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A25%3A38Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/448783%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/stubailo%22%7D%7D%5D%2C%20%22title%22%3A%20%22File%3A%20content/data-loading.md%3AL1-557%22%7D%2C%20%22Pull%20398878f1a3d4b1d7943e9c9b22fec82af9957928%20content/data-loading.md%2073%22%3A%20%7B%22html_url%22%3A%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576576%22%2C%20%22comments%22%3A%20%5B%7B%22body%22%3A%20%22This%20should%20be%20co-located%20with%20the%20code.%20Perhaps%20this%20could%20even%20be%20a%20comment.%20We%27ll%20have%20a%20whole%20bit%20on%20this%20in%20the%20security%20article.%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A21%3A08Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/448783%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/stubailo%22%7D%7D%5D%2C%20%22title%22%3A%20%22File%3A%20content/data-loading.md%3AL1-557%22%7D%2C%20%22Pull%20398878f1a3d4b1d7943e9c9b22fec82af9957928%20content/data-loading.md%20111%22%3A%20%7B%22html_url%22%3A%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576734%22%2C%20%22comments%22%3A%20%5B%7B%22body%22%3A%20%22You%20could%20also%20use%20a%20subset%20of%20the%20query%2C%20but%20perhaps%20that%27s%20not%20really%20important%3F%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A26%3A08Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/448783%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/stubailo%22%7D%7D%5D%2C%20%22title%22%3A%20%22File%3A%20content/data-loading.md%3AL1-557%22%7D%2C%20%22Pull%20398878f1a3d4b1d7943e9c9b22fec82af9957928%20content/data-loading.md%2055%22%3A%20%7B%22html_url%22%3A%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576527%22%2C%20%22comments%22%3A%20%5B%7B%22body%22%3A%20%22This%20is%20an%20_important%20point_%20-%20we%20should%20call%20out%20somewhere%20big%20that%20if%20you%20don%27t%20return%20an%20array%2C%20or%20call%20%60this.ready%60%2C%20the%20publication%20will%20_never_%20be%20marked%20ready%2C%20which%20results%20in%20all%20kinds%20of%20crappy%20bugs.%20%28Even%20returning%20%60null%60%20is%20not%20enough%2C%20lol.%20I%20think%20we%20should%20fix%20this%20somehow%20in%20a%20future%20version%20of%20Meteor.%29%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A19%3A49Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/448783%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/stubailo%22%7D%7D%2C%20%7B%22body%22%3A%20%22Also%2C%20we%20should%20mention%20what%20it%20means%20for%20a%20subscription%20to%20be%20ready%20-%20namely%2C%20this%20is%20used%20to%20fire%20the%20%60ready%60%20callback%20on%20the%20client.%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A20%3A23Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/448783%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/stubailo%22%7D%7D%2C%20%7B%22body%22%3A%20%22I%27m%20not%20sure%20why%20we%20even%20have%20the%20same%20API%20for%20publications%20that%20return%20cursors.%20Why%20not%20just%20%60Meteor.publishCursor%60%3F%20--%20then%20if%20it%20doesn%27t%20return%20anything%2C%20you%20know%20it%27s%20done.%5Cr%5Cn%5Cr%5CnOverloading%20%60Meteor.publish%60%20was%20a%20mistake%2C%20IMO.%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A22%3A54Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/132554%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/tmeasday%22%7D%7D%5D%2C%20%22title%22%3A%20%22File%3A%20content/data-loading.md%3AL1-557%22%7D%2C%20%22Pull%20398878f1a3d4b1d7943e9c9b22fec82af9957928%20content/data-loading.md%2087%22%3A%20%7B%22html_url%22%3A%20%22https%3A//github.com/meteor/guide/pull/97%23discussion_r45576641%22%2C%20%22comments%22%3A%20%5B%7B%22body%22%3A%20%22It%27s%20not%20clear%20here%20why%20%5C%22action%20at%20a%20distance%5C%22%20might%20happen%20-%20I%20think%20we%20should%20call%20out%20that%20making%20a%20subscription%20means%20potentially%20all%20queries%20on%20that%20collection%20could%20get%20new%20data.%22%2C%20%22created_at%22%3A%20%222015-11-23T07%3A23%3A23Z%22%2C%20%22user%22%3A%20%7B%22avatar_url%22%3A%20%22https%3A//avatars.githubusercontent.com/u/448783%3Fv%3D3%22%2C%20%22html_url%22%3A%20%22https%3A//github.com/stubailo%22%7D%7D%5D%2C%20%22title%22%3A%20%22File%3A%20content/data-loading.md%3AL1-557%22%7D%7D%7D'></a>\n<a href='https://www.codereviewhub.com/'><img src='http://www.codereviewhub.com/site/github-bar.png' height=40></a>\n- [ ] <a href='#crh-comment-Pull 398878f1a3d4b1d7943e9c9b22fec82af9957928 content/data-loading.md 55'></a> <img src='http://www.codereviewhub.com/site/github-remaining.png' height=16 width=60>&nbsp;<b><a href='https://github.com/meteor/guide/pull/97#discussion_r45576527'>File: content/data-loading.md:L1-557</a></b>\n- <a href='https://github.com/stubailo'><img border=0 src='https://avatars.githubusercontent.com/u/448783?v=3' height=16 width=16'></a> This is an _important point_ - we should call out somewhere big that if you don't return an array, or call `this.ready`, the publication will _never_ be marked ready, which results in all kinds of crappy bugs. (Even returning `null` is not enough, lol. I think we should fix this somehow in a future version of Meteor.)\n- <a href='https://github.com/stubailo'><img border=0 src='https://avatars.githubusercontent.com/u/448783?v=3' height=16 width=16'></a> Also, we should mention what it means for a subscription to be ready - namely, this is used to fire the `ready` callback on the client.\n- <a href='https://github.com/tmeasday'><img border=0 src='https://avatars.githubusercontent.com/u/132554?v=3' height=16 width=16'></a> I'm not sure why we even have the same API for publications that return cursors. Why not just `Meteor.publishCursor`? -- then if it doesn't return anything, you know it's done.\nOverloading `Meteor.publish` was a mistake, IMO.\n- [ ] <a href='#crh-comment-Pull 398878f1a3d4b1d7943e9c9b22fec82af9957928 content/data-loading.md 73'></a> <img src='http://www.codereviewhub.com/site/github-remaining.png' height=16 width=60>&nbsp;<b><a href='https://github.com/meteor/guide/pull/97#discussion_r45576576'>File: content/data-loading.md:L1-557</a></b>\n- <a href='https://github.com/stubailo'><img border=0 src='https://avatars.githubusercontent.com/u/448783?v=3' height=16 width=16'></a> This should be co-located with the code. Perhaps this could even be a comment. We'll have a whole bit on this in the security article.\n- [ ] <a href='#crh-comment-Pull 398878f1a3d4b1d7943e9c9b22fec82af9957928 content/data-loading.md 87'></a> <img src='http://www.codereviewhub.com/site/github-remaining.png' height=16 width=60>&nbsp;<b><a href='https://github.com/meteor/guide/pull/97#discussion_r45576641'>File: content/data-loading.md:L1-557</a></b>\n- <a href='https://github.com/stubailo'><img border=0 src='https://avatars.githubusercontent.com/u/448783?v=3' height=16 width=16'></a> It's not clear here why \"action at a distance\" might happen - I think we should call out that making a subscription means potentially all queries on that collection could get new data.\n- [ ] <a href='#crh-comment-Pull 398878f1a3d4b1d7943e9c9b22fec82af9957928 content/data-loading.md 103'></a> <img src='http://www.codereviewhub.com/site/github-remaining.png' height=16 width=60>&nbsp;<b><a href='https://github.com/meteor/guide/pull/97#discussion_r45576682'>File: content/data-loading.md:L1-557</a></b>\n- <a href='https://github.com/stubailo'><img border=0 src='https://avatars.githubusercontent.com/u/448783?v=3' height=16 width=16'></a> Actually, Meteor.subscribe would also tear down the subscription because of how autorun works, but the real benefit is being able to use `Template.instance().subscriptionsReady()`. (This was designed to replace `waitOn` in Iron Router :] )\n- <a href='https://github.com/tmeasday'><img border=0 src='https://avatars.githubusercontent.com/u/132554?v=3' height=16 width=16'></a> Oh right, :blush:\n- [ ] <a href='#crh-comment-Pull 398878f1a3d4b1d7943e9c9b22fec82af9957928 content/data-loading.md 109'></a> <img src='http://www.codereviewhub.com/site/github-remaining.png' height=16 width=60>&nbsp;<b><a href='https://github.com/meteor/guide/pull/97#discussion_r45576714'>File: content/data-loading.md:L1-557</a></b>\n- <a href='https://github.com/stubailo'><img border=0 src='https://avatars.githubusercontent.com/u/448783?v=3' height=16 width=16'></a> \"Subscribing to data puts it in your client-side collections. To use the data in your templates, you need to query...\"\n- [ ] <a href='#crh-comment-Pull 398878f1a3d4b1d7943e9c9b22fec82af9957928 content/data-loading.md 111'></a> <img src='http://www.codereviewhub.com/site/github-remaining.png' height=16 width=60>&nbsp;<b><a href='https://github.com/meteor/guide/pull/97#discussion_r45576734'>File: content/data-loading.md:L1-557</a></b>\n- <a href='https://github.com/stubailo'><img border=0 src='https://avatars.githubusercontent.com/u/448783?v=3' height=16 width=16'></a> You could also use a subset of the query, but perhaps that's not really important?\n- [ ] <a href='#crh-comment-Pull 398878f1a3d4b1d7943e9c9b22fec82af9957928 content/data-loading.md 121'></a> <img src='http://www.codereviewhub.com/site/github-remaining.png' height=16 width=60>&nbsp;<b><a href='https://github.com/meteor/guide/pull/97#discussion_r45576786'>File: content/data-loading.md:L1-557</a></b>\n- <a href='https://github.com/stubailo'><img border=0 src='https://avatars.githubusercontent.com/u/448783?v=3' height=16 width=16'></a> Although you don't want to pass it through as an argument everywhere, I'd still recommend being judicious with where you use it, since it could make your components more annoying to test.\n\n\n<a href='https://www.codereviewhub.com/meteor/guide/pull/97?mark_as_completed=1'><img src='http://www.codereviewhub.com/site/github-mark-as-completed.png' height=26></a>&nbsp;<a href='https://www.codereviewhub.com/meteor/guide/pull/97?approve=1'><img src='http://www.codereviewhub.com/site/github-approve.png' height=26></a>&nbsp;<a href='https://github.com/meteor/guide/pull/97'><img src='http://www.codereviewhub.com/site/github-refresh.png' height=26></a>\n<a href='#crh-end'></a>","created_at":"2015-11-18T05:13:49Z","updated_at":"2015-11-23T07:28:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8285e877f67c9b1e87caa172c580c9a74ff75f3f","assignee":{"login":"stubailo","id":448783,"avatar_url":"https://avatars.githubusercontent.com/u/448783?v=3","gravatar_id":"","url":"https://api.github.com/users/stubailo","html_url":"https://github.com/stubailo","followers_url":"https://api.github.com/users/stubailo/followers","following_url":"https://api.github.com/users/stubailo/following{/other_user}","gists_url":"https://api.github.com/users/stubailo/gists{/gist_id}","starred_url":"https://api.github.com/users/stubailo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stubailo/subscriptions","organizations_url":"https://api.github.com/users/stubailo/orgs","repos_url":"https://api.github.com/users/stubailo/repos","events_url":"https://api.github.com/users/stubailo/events{/privacy}","received_events_url":"https://api.github.com/users/stubailo/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/meteor/guide/pulls/97/commits","review_comments_url":"https://api.github.com/repos/meteor/guide/pulls/97/comments","review_comment_url":"https://api.github.com/repos/meteor/guide/pulls/comments{/number}","comments_url":"https://api.github.com/repos/meteor/guide/issues/97/comments","statuses_url":"https://api.github.com/repos/meteor/guide/statuses/398878f1a3d4b1d7943e9c9b22fec82af9957928","head":{"label":"meteor:data-loading-content","ref":"data-loading-content","sha":"398878f1a3d4b1d7943e9c9b22fec82af9957928","user":{"login":"meteor","id":789528,"avatar_url":"https://avatars.githubusercontent.com/u/789528?v=3","gravatar_id":"","url":"https://api.github.com/users/meteor","html_url":"https://github.com/meteor","followers_url":"https://api.github.com/users/meteor/followers","following_url":"https://api.github.com/users/meteor/following{/other_user}","gists_url":"https://api.github.com/users/meteor/gists{/gist_id}","starred_url":"https://api.github.com/users/meteor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/meteor/subscriptions","organizations_url":"https://api.github.com/users/meteor/orgs","repos_url":"https://api.github.com/users/meteor/repos","events_url":"https://api.github.com/users/meteor/events{/privacy}","received_events_url":"https://api.github.com/users/meteor/received_events","type":"Organization","site_admin":false},"repo":{"id":43717321,"name":"guide","full_name":"meteor/guide","owner":{"login":"meteor","id":789528,"avatar_url":"https://avatars.githubusercontent.com/u/789528?v=3","gravatar_id":"","url":"https://api.github.com/users/meteor","html_url":"https://github.com/meteor","followers_url":"https://api.github.com/users/meteor/followers","following_url":"https://api.github.com/users/meteor/following{/other_user}","gists_url":"https://api.github.com/users/meteor/gists{/gist_id}","starred_url":"https://api.github.com/users/meteor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/meteor/subscriptions","organizations_url":"https://api.github.com/users/meteor/orgs","repos_url":"https://api.github.com/users/meteor/repos","events_url":"https://api.github.com/users/meteor/events{/privacy}","received_events_url":"https://api.github.com/users/meteor/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/meteor/guide","description":"How do I use Meteor?","fork":false,"url":"https://api.github.com/repos/meteor/guide","forks_url":"https://api.github.com/repos/meteor/guide/forks","keys_url":"https://api.github.com/repos/meteor/guide/keys{/key_id}","collaborators_url":"https://api.github.com/repos/meteor/guide/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/meteor/guide/teams","hooks_url":"https://api.github.com/repos/meteor/guide/hooks","issue_events_url":"https://api.github.com/repos/meteor/guide/issues/events{/number}","events_url":"https://api.github.com/repos/meteor/guide/events","assignees_url":"https://api.github.com/repos/meteor/guide/assignees{/user}","branches_url":"https://api.github.com/repos/meteor/guide/branches{/branch}","tags_url":"https://api.github.com/repos/meteor/guide/tags","blobs_url":"https://api.github.com/repos/meteor/guide/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/meteor/guide/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/meteor/guide/git/refs{/sha}","trees_url":"https://api.github.com/repos/meteor/guide/git/trees{/sha}","statuses_url":"https://api.github.com/repos/meteor/guide/statuses/{sha}","languages_url":"https://api.github.com/repos/meteor/guide/languages","stargazers_url":"https://api.github.com/repos/meteor/guide/stargazers","contributors_url":"https://api.github.com/repos/meteor/guide/contributors","subscribers_url":"https://api.github.com/repos/meteor/guide/subscribers","subscription_url":"https://api.github.com/repos/meteor/guide/subscription","commits_url":"https://api.github.com/repos/meteor/guide/commits{/sha}","git_commits_url":"https://api.github.com/repos/meteor/guide/git/commits{/sha}","comments_url":"https://api.github.com/repos/meteor/guide/comments{/number}","issue_comment_url":"https://api.github.com/repos/meteor/guide/issues/comments{/number}","contents_url":"https://api.github.com/repos/meteor/guide/contents/{+path}","compare_url":"https://api.github.com/repos/meteor/guide/compare/{base}...{head}","merges_url":"https://api.github.com/repos/meteor/guide/merges","archive_url":"https://api.github.com/repos/meteor/guide/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/meteor/guide/downloads","issues_url":"https://api.github.com/repos/meteor/guide/issues{/number}","pulls_url":"https://api.github.com/repos/meteor/guide/pulls{/number}","milestones_url":"https://api.github.com/repos/meteor/guide/milestones{/number}","notifications_url":"https://api.github.com/repos/meteor/guide/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/meteor/guide/labels{/name}","releases_url":"https://api.github.com/repos/meteor/guide/releases{/id}","created_at":"2015-10-05T22:26:02Z","updated_at":"2015-11-22T20:58:53Z","pushed_at":"2015-11-23T03:17:02Z","git_url":"git://github.com/meteor/guide.git","ssh_url":"git@github.com:meteor/guide.git","clone_url":"https://github.com/meteor/guide.git","svn_url":"https://github.com/meteor/guide","homepage":"","size":3635,"stargazers_count":362,"watchers_count":362,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":25,"mirror_url":null,"open_issues_count":62,"forks":25,"open_issues":62,"watchers":362,"default_branch":"master"}},"base":{"label":"meteor:master","ref":"master","sha":"71f92e73e0ffa6873b675bb17261104da2ae3d85","user":{"login":"meteor","id":789528,"avatar_url":"https://avatars.githubusercontent.com/u/789528?v=3","gravatar_id":"","url":"https://api.github.com/users/meteor","html_url":"https://github.com/meteor","followers_url":"https://api.github.com/users/meteor/followers","following_url":"https://api.github.com/users/meteor/following{/other_user}","gists_url":"https://api.github.com/users/meteor/gists{/gist_id}","starred_url":"https://api.github.com/users/meteor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/meteor/subscriptions","organizations_url":"https://api.github.com/users/meteor/orgs","repos_url":"https://api.github.com/users/meteor/repos","events_url":"https://api.github.com/users/meteor/events{/privacy}","received_events_url":"https://api.github.com/users/meteor/received_events","type":"Organization","site_admin":false},"repo":{"id":43717321,"name":"guide","full_name":"meteor/guide","owner":{"login":"meteor","id":789528,"avatar_url":"https://avatars.githubusercontent.com/u/789528?v=3","gravatar_id":"","url":"https://api.github.com/users/meteor","html_url":"https://github.com/meteor","followers_url":"https://api.github.com/users/meteor/followers","following_url":"https://api.github.com/users/meteor/following{/other_user}","gists_url":"https://api.github.com/users/meteor/gists{/gist_id}","starred_url":"https://api.github.com/users/meteor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/meteor/subscriptions","organizations_url":"https://api.github.com/users/meteor/orgs","repos_url":"https://api.github.com/users/meteor/repos","events_url":"https://api.github.com/users/meteor/events{/privacy}","received_events_url":"https://api.github.com/users/meteor/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/meteor/guide","description":"How do I use Meteor?","fork":false,"url":"https://api.github.com/repos/meteor/guide","forks_url":"https://api.github.com/repos/meteor/guide/forks","keys_url":"https://api.github.com/repos/meteor/guide/keys{/key_id}","collaborators_url":"https://api.github.com/repos/meteor/guide/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/meteor/guide/teams","hooks_url":"https://api.github.com/repos/meteor/guide/hooks","issue_events_url":"https://api.github.com/repos/meteor/guide/issues/events{/number}","events_url":"https://api.github.com/repos/meteor/guide/events","assignees_url":"https://api.github.com/repos/meteor/guide/assignees{/user}","branches_url":"https://api.github.com/repos/meteor/guide/branches{/branch}","tags_url":"https://api.github.com/repos/meteor/guide/tags","blobs_url":"https://api.github.com/repos/meteor/guide/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/meteor/guide/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/meteor/guide/git/refs{/sha}","trees_url":"https://api.github.com/repos/meteor/guide/git/trees{/sha}","statuses_url":"https://api.github.com/repos/meteor/guide/statuses/{sha}","languages_url":"https://api.github.com/repos/meteor/guide/languages","stargazers_url":"https://api.github.com/repos/meteor/guide/stargazers","contributors_url":"https://api.github.com/repos/meteor/guide/contributors","subscribers_url":"https://api.github.com/repos/meteor/guide/subscribers","subscription_url":"https://api.github.com/repos/meteor/guide/subscription","commits_url":"https://api.github.com/repos/meteor/guide/commits{/sha}","git_commits_url":"https://api.github.com/repos/meteor/guide/git/commits{/sha}","comments_url":"https://api.github.com/repos/meteor/guide/comments{/number}","issue_comment_url":"https://api.github.com/repos/meteor/guide/issues/comments{/number}","contents_url":"https://api.github.com/repos/meteor/guide/contents/{+path}","compare_url":"https://api.github.com/repos/meteor/guide/compare/{base}...{head}","merges_url":"https://api.github.com/repos/meteor/guide/merges","archive_url":"https://api.github.com/repos/meteor/guide/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/meteor/guide/downloads","issues_url":"https://api.github.com/repos/meteor/guide/issues{/number}","pulls_url":"https://api.github.com/repos/meteor/guide/pulls{/number}","milestones_url":"https://api.github.com/repos/meteor/guide/milestones{/number}","notifications_url":"https://api.github.com/repos/meteor/guide/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/meteor/guide/labels{/name}","releases_url":"https://api.github.com/repos/meteor/guide/releases{/id}","created_at":"2015-10-05T22:26:02Z","updated_at":"2015-11-22T20:58:53Z","pushed_at":"2015-11-23T03:17:02Z","git_url":"git://github.com/meteor/guide.git","ssh_url":"git@github.com:meteor/guide.git","clone_url":"https://github.com/meteor/guide.git","svn_url":"https://github.com/meteor/guide","homepage":"","size":3635,"stargazers_count":362,"watchers_count":362,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":25,"mirror_url":null,"open_issues_count":62,"forks":25,"open_issues":62,"watchers":362,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/meteor/guide/pulls/97"},"html":{"href":"https://github.com/meteor/guide/pull/97"},"issue":{"href":"https://api.github.com/repos/meteor/guide/issues/97"},"comments":{"href":"https://api.github.com/repos/meteor/guide/issues/97/comments"},"review_comments":{"href":"https://api.github.com/repos/meteor/guide/pulls/97/comments"},"review_comment":{"href":"https://api.github.com/repos/meteor/guide/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/meteor/guide/pulls/97/commits"},"statuses":{"href":"https://api.github.com/repos/meteor/guide/statuses/398878f1a3d4b1d7943e9c9b22fec82af9957928"}}}}