Search code examples
javascriptmeteorhandlebars.jsiron-router

Show Action via iron:router, template isn't passed data from a collection.findOne method


I can't get a the 'show' page of an instance of a model to display its data.

Here's the template that won't show its data:

<template name="priority">
  <h1>Priority: {{title}}</h1>
</template>

It's very simple in and of itself, yet I can't get title to display. Iron:router does the job of directing us to this page with the following code:

Router.route('/priority/:_id', function(){
  var priority = this.params._id; 
  this.render('priority', {
    data: function(priority){
      Meteor.call('showPriority', priority, function(error){
        if (error) {
          console.log("An error has occured: " + error); 
        }
      })
    }
  })
},  {
  name: 'priority.show'
});

The Meteor.method is very simple, it just queries for the variable priority:

'showPriority': function(priority) { 
    return Priorities.findOne({_id: priority});
  }

The view which carries the href is here:

<template name="priorityList">
  <ul class="table-view">
    {{#each this}}
    <li class="table-view-cell">
      {{title}}
      <a href="{{pathFor route="priority.show"}}"><span class="pull-right icon icon-edit"></span></a>
    </li>
    {{/each}}
  </ul>
</template>

Note that this view shows a list of all priorities. When I inspect the href, all the paths are being dynamically generated with an _id:

<a href="/priority/yYihyZmZ2xkAso7i5">...

Oh, and I should mention, that I also tried to use the waitOn method, since I thought I might be loading the template before the data, but that didn't help either...

Router.configure({
  ...
  waitOn: function(){
    return Meteor.subscribe('priorities');
  }
});

So much code, just to show what's going on!

What's the deal here? Why won't my "show" template give me any data?


Solution

  • Change you route to this.

    Router.map(function () {
      this.route('priority', {
        path: '/priority/:_id',
        waitOn: function(){
            return Meteor.subscribe('priorities',this.params._id);
        },
        data: function(){
          if(this.ready()){
             return Priorities.findOne({_id: this.params._id});
           }else{
            this.render('loading') //if data not ready we render some loading template
          }
        }
      });
    });
    

    You don't need to make a Meteor.call, for the find(); instead to everything on the data:function()

    The above is just an example so you can get the idea, but it should work since you are expecting _id:priority and _id:this.params._id its the same.

    Just be sure you have the autopublish package removed.

    and have the subscriptions/publish in order.

    Meteor.publish('Menu', function(){
              return Priorities.find();
            });