0
votes

I am really struggling with waiting on a subscription to load for a specific route before returning the data to the template. I can see on from the publish on the server that a document is found, but on the client there is no document.

If I do a find().count() on the publish, it shows 1 document found, which is correct, but when I do the count on the subscription, it shows 0 documents.

I have tried a number of different methods, like using subscriptions:function() instead of waitOn:function(), but nothing works.

Collections.js lib:

SinglePackage = new Mongo.Collection("SinglePackage");
SinglePackage.allow({
  insert: function(){
    return true;
  },
  update: function(){
    return true;
  },
  remove: function(){
    return true;
  }
});

Publications.js server:

Meteor.publish("SinglePackage", function(pack_id) {
 return Packages.find({shortId: pack_id});
});

Iron Router:

Router.route('/package/:id', {
  name: 'package.show',
  template: 'Package_page',
  layoutTemplate: 'Landing_layout',
  waitOn: function() {
    return Meteor.subscribe('SinglePackage', this.params.id);
  },
  data: function() {
    return SinglePackage.find();
  },
  action: function () {
    if (this.ready()) {
      this.render();
    } else {
      this.render('Loading');
    }
  }
});

Am I doing something very wrong, or is this just a complicated thing to achieve? One would think that waitOn would make the rest of the function wait until the subscription is ready.

Any help would be highly appreciated.

1

1 Answers

0
votes

It appears that the data function is running before the subscription is ready. Even if the data function did run after the subscription was ready, it wouldn't be a reactive data source rendering the pub/sub here pointless. Here's a great article on reactive data sources.

Referring to the example from the Iron Router Docs for subscriptions, you would do something like this:

Router.route('/package/:id', {
  subscriptions: function() {
    // returning a subscription handle or an array of subscription handles
    // adds them to the wait list.
    return Meteor.subscribe('SinglePackage', this.params.id);
  },

  action: function () {
    if (this.ready()) {
      this.render();
    } else {
      this.render('Loading');
    }
  }
});

Then in your template.js:

Template.Package_page.helpers({
  singlePackage() {
  // This is now a reactive data source and will automatically update whenever SinglePackage changes in Mongo.
    return Package.find().fetch();
  }
}); 

In your template.html you can now use singlePackage:

<template name="Package_page">
  {#with singlePackage} <!-- Use #each if you're singlePackage is an array -->
    ID: {_id}
  {/with}
</template>