2

I am frustrated with the lack of documentation around Iron Router and Collections/publish/subscribe. I have some Publish statements (on the isServer part of the code in the site) that return data from Collections to the client. I call them in the route like this:

Router.route('/project/:_id', {
  path: '/project/:_id',
  template: 'project',
  waitOn: function(){
    return Meteor.subscribe( "getProject", this.params._id );
  }

At this point, I have a server capable of sending a published data set to the client. I have a client asking to subscribe to that data set. That should be all I need for a functional page, right? BUT, Iron Router barks at me when I don't include a data: field like this in the Route:

data: function() {
  return Projects.find();
}

Why do I need a data: if I should already have the data I want on the Meteor.subscribe? Can someone explain why this is necessary? I don't want Projects.find() results in the Template, I want the result of Meteor.subscribe("getProject"). Tried to call getProject in the data: part but it wants a collection not a publish/subscription.

This is frustrating because it seems like the most basic task: render a page and use the result set provided by the server. Am I missing something more than that? Basic LAMP can render data pretty easily.

Crash Override
  • 1,337
  • 3
  • 13
  • 26

2 Answers2

4

On this piece of code.

waitOn: function(){
    return Meteor.subscribe( "getProject", this.params._id );
  }

Like the name say you are waiting to the client, get the "data ready" Aka the subscription.

And about the data:function() field on others word "template data", lets put in on an example.

Lets say you have this template.

<template name="projects">
  <h2>A List Of Projects</h2>
 <!-- here you want to show something like {{projectName}}. --> 
</template>

So you need to pass data into the the template right?

So you can pass data as a function or as an object

you can pass

data:function(){
  return Projects.find() //for example
} 

or

data:{
   projects:[{
     title:"example"
      },
      {
     title:"example2"
      }
    ]
 }

You need also know if you use the data as a function you don't need the {{#each}} helper on the template, but if you use it like an object you will need to do the follow

{{#each projects}}
   {{title}}
{{/each}}

Or you can just omit the data on the iron router and create your own helpers

Template.example.helpers({
  projects:function(){
    return Projects.find(); //this will do the same as data:function(){} iron router method
  }
})

Hope you get it

Ethaan
  • 11,291
  • 5
  • 35
  • 45
  • Thanks Ethaan but the problem is the data I want to use within the Template is NOT just a collection. I'm trying to include a sub function that grabs something out of the Meteor.users collection about the "owner" of the Project. One of the Project's attributes is the ownerid (the _id from the Meteor.users collection). I want to sub the owner's email address (or another attribute) from the Meteor.users collection, include that in the result set (or as a function for the Template), so I can call {{user_email_address}} or the equivalent. This seems simple conceptually (is not a fancy join) – Crash Override Feb 17 '15 at 03:52
  • So Projects.find() is not enough. But in the meteor publish, looks like it can include a sub function in the result set. – Crash Override Feb 17 '15 at 03:53
  • my friend i don't really get it, you can just put on the template `{{if currentUser}} {{/if}}` or just do this. `{{currentUser.profile.name}}` – Ethaan Feb 17 '15 at 03:56
  • The ownerID of the Project is not necessarilly the currently logged in user. – Crash Override Feb 17 '15 at 04:05
  • Ethaan helped me after an online chat session. We removed the data: field from the Iron Router. Then we created 2 helper functions: Template.project.helpers({ showProjects: function() { return { Projects.find() } }, owerInformation:function(owna) { return Meteor.users.find({_id:owna}); } I don't have this code working 100% yet- the owerInformation:function doesn't seem to like the variable I'm passing into it yet, but this method (using Template helpers) looks easier than trying to do a publish/subscribe. I'll continue playing with it this way, see how far I get. – Crash Override Feb 17 '15 at 06:25
  • @Crash override the subscription/publish are actually required, the thing we do on chat was removing the data:function and use a helper – Ethaan Feb 17 '15 at 06:32
  • Ok I'm starting to understand more now. So the subscription/publish is required whenever you have data to communicate between the client and server. So that's always needed. Question though, when using a helper function to grab just the ownerid's user data, what does the subscription look like? I don't want to tell the client to subscribe to Meteor.users.find() because it gives the client access to all users' data. – Crash Override Feb 17 '15 at 06:53
  • Think I found a possible solution to how to Publish/Subscribe to the data I need to access from the Template helpers. http://stackoverflow.com/questions/13151879/publish-certain-information-for-meteor-users-and-more-information-for-meteor-use – Crash Override Feb 17 '15 at 13:45
0

Yes, you still have to call find on any collection you need data from. A subscription just makes that data, that would normally only exist on the server side, available on the client side. A subscription pulls down the stuff you need for that given user. For example, you don't want all projects, you only want the projects that belong to the current user.

If you have the autopublish package installed, you wont need subscriptions as all clients will have all the data; without it you need to specify only what you need.

Jason Cochran
  • 316
  • 3
  • 10
  • I get that a subscription opens the door to a data result set. It's THAT data that I want rendered on my page because it contains server logic to assemble & return that data to the client. Then why do I need a SECOND result set in the data: field? It seems like Iron Router wants 2 result sets to render my Route. Am I missing something? – Crash Override Feb 17 '15 at 00:48
  • Previous comment refers to the need for a data: field at all. Why need it, when I'm already subscribing to the data I want? – Crash Override Feb 17 '15 at 00:57