Search code examples
meteorflow-router

Meteor exception in template handler


This problem resembles the one found here, specifically, my Meteor application does what it's supposed to but dumps an ugly error into the console along these lines:

[Log] Exception in template helper: project@http://localhost:3000/app/app.js?hash=9d27a5d54ce7e2e0519a4359c523c992bfdc3894:991:54 (meteor.js, line 930)
...60 lines snipped...
onclick@http://localhost:3000/packages/kadira_flow-router.js?hash=a7cc426e8dadbfad936f4f03bda0e74ded30ae36:1617:14

The answer to the other linked question suggests that it's caused by an attempt to access an object when it hasn't yet been loaded. However, I've attempted to prevent this as follows.

The data come from the server's main.js thus:

Meteor.publish('oneCount', function countPublication(countId) {
    let oneCount = Counts.find({_id: countId});
    return oneCount
});

Now, the Flow Router config:

FlowRouter.route('/edit_count/:countId', {
    subscriptions: function(params) {
        this.register('currentCount', Meteor.subscribe('oneCount', params.countId));
    },
    action: function(params) {
        BlazeLayout.render('MainLayout', {content: 'EditCount', countId: params.countId})
    }
 });

And, In the EditCount template and associated javascript:

 {{#if isReady }}
     ...
     <a class="btn" href="/count/{{ project }}">Project</a>
     ...
 {{else}}
     {{> Loading}}
 {{/if}}

 Template.EditCount.helpers({
    project: function() {
        const project = Projects.findOne({counts: this.countId()});
        return project._id;

    },
    isReady: function(sub) {
        if(sub) {
            return FlowRouter.subsReady(sub);
        } else {
            return FlowRouter.subsReady();
        }
     }
 })

The error I got doesn't refer to a particular part of my code, mostly blaze and flow-router.

I have read that it might now be considered poor form to have the subscriptions in the router, so I have replaced the code with this:

FlowRouter.route('/edit_count/:countId', {
    name: 'edit_count',
    action: function(params) {
        BlazeLayout.render('MainLayout', {content: 'EditCount', countId: params.countId})
    }
});

Template.EditCount.onCreated(function() {
    this.subscribe('oneCount', this.countId());
})

...then, using Template.subscriptionsReady in the template rather than the isReady function. But, now nothing renders and I get Exception in defer callback from app.js.

If anyone has any recommendation as to which would be the best pattern to pursue and how to fix it then that would be greatly appreciated.

EDIT:

I removed subscriptions from all the routes and put them in the template instead. If I try to use publications where a single result is returned then I get the Exception in defer callback error above, but subscribing to a publication of all records fixed this. However, despite now subscribing in the template I still get the Exception in template helper, which is rather frustrating.


Solution

  • Eventually, the solution turned out to be here. Specifically:

    • Putting the subscription in an autorun block in the template .js file.
    • Getting the FlowRouter parameters in the template helpers.
    • Wrapping the UI code with {{#with currentProject}} (or whatever) tags.