Tabular, publish_composite, iron:router - no data

I am trying to use iron:router, aldeed tabular, and reywood:publish_composite. I want to show a list of Building names with their region’s name (2 columns). My table shows up but there is no data.Can anybody spot the problem?

I have a Buildings collection and a Regions collection. Building.region is keyed to Regions._id

Here is my route in /lib.routes.js

Router.route('/buildings', {
  name: 'buildings',
  template: 'buildings',
  onAfterAction: function() {
    document.title = "Buildings";
  }
});

/server/publish.js

Meteor.publishComposite("tabularBuildings", function(tableName, ids, fields) {
  check(tableName, String);
  check(ids, Array);
  check(fields, Match.Optional(Object));
  this.unblock();
  return {
    find: function() {
      this.unblock()
      Buildings.find({_id: {$in: ids}}, {fields: fields});
    },
    children: [
    {
      find: function(building) {
        this.unblock();
        return Regions.find({_id: building.region}, {limit: 1, fields: {name: 1}, sort: {_id: 1}});
      }
    }]
  }
});

/common/tables.js

TabularTables = {};
TabularTables.Buildings = new Tabular.Table({
  name: "Buildings",
  collection: Buildings,
  pub: 'tabularBuildings',
  responsive: true,
  paging: false,
  scrollY: 200,
  scrollCollapse: true,
  bFilter: false,
  order: [[0, "asc"]],
  columns: [
    {data: "name", title: "Building Name"},
    {data: "region_name()", title: "Region"}
  ]
});

in /client/building/building.html

{{> tabular table=TabularTables.Buildings class="table table-striped"}}

UPDATE - I’ve noticed that the footer of the table reads “Showing 1 to 0 of 20 entries”. There are in fact 20 buildings in the Buildings collection.

UPDATE #2 - The footer starts out reading “Showing 0 to 0 of 0 entries”. It is only when I click a column header to sort, that the footer changes to read “Showing 1 to 0 of 20 entries”

you can see the problem here
login with field@some.com and pass 12345, then go to ‘View Buildings’

Does the buildings route need to have the following (or some other code?

waitOn: function() {
     this.subscribe("tabularBuildings");
}

I tried this code, but it didn’t have any effect. I thought I saw somewhere that the tabular package handles its own subscription.

When I add the following code to /server/publish.js I get no output in the console:

Meteor.publish("tablularBuildings", function(tableName, ids, fields) {
   console.log("tbl: "+tableName);
   console.log("ids: "+ids);
   console.log("fld: "+fields);
   return Buildings.find({_id: {$in: ids}}, {fields: fields});
});

Note: When I try the above publish function, I change the columns on the table definition to ‘region’ instead of ‘region_name()’. I’m trying to simplify the code untill I get it to work and then I will build it back up.

Just took a quick look – Buildings.find().count() returns 0, which means your data isn’t getting to the client. Maybe start without a custom publication and see if you can even get your data?

I just posted a GitHub repo here to help with this discussion. I’ve also updatedthe site here with the code I’m talking about here.

to /server/publish.js I added

Meteor.publish("buildingsForList", function() {
  return Buildings.find({}, {fields: {_id:1}});
});

to my buildings route in /lib/routes.js I changed

Router.route('/buildings', {
  name: 'buildings',
  template: 'buildings',
  loadingTemplate: 'loading',
  waitOn: function() {
    this.subscribe("buildingsForList");
  }
});

The table definition in /common/tableBuildings.js still has

pub: 'tabularBuildings',
columns: [
  {data: "name", title: "Building Name"},
  {data: 'region_name()', title: "Region"}
]

The table now has 20 rows, but they are all emply. When I add name:1 to the buildingsForList publish, the buildings name will show up in the table.

Somehow, I think I’m doing this incorrectly. This code is subscribing to the entire Building collection (thus downloading the entire collection to the client). The whole point of using tabular is to avoid subscribing to the entire set of documents.

You can use selectors to help control the flow of data. A selector in the constructor will limit the published data, while a selector in the component will limit the displayed data.

I don’t understand why I need two publications to make this work.

What’s more, if I type Buildings.find().fetch() it gives me a list of 20 buildings. each of them look like this;

{ _id="b213nqeIHolilKJ", region_name=region_name() }

Typing Buildings.find().fetch()[0].region_name() gives undefined.

The collection knows that region_name() is supposed to be there, but the name, and region_name are not accessible.

This is getting highly frustrating.

Well, there is only very little chatter here. Thank you for your suggestions @vigorwebsolutions

I have a feeling that iron:router may be blocking the tabularBuildings pub/sub and so I’m thinking about changing over to flow:router. I will do some testing and report back.

1 Like