tomet
tomet

Reputation: 2556

Iron router: Don't re-render page if wait on changes

I subscribe to a collection using iron router's waitOn functionality. This subscription is dependent on a Session variable.When the Session variable changes, the subscription should be renewed using the new value of the Session variable.

This works fine, but there's one problem: When the session variable changes, the page does a complete rerender. However, I just want the data to change.

Is it somehow possible to avoid this rerendering behavior and just resubscribe when the Session variable changes?

Thank you,

Tony

Upvotes: 0

Views: 348

Answers (3)

lassombra
lassombra

Reputation: 427

What you want is to only wait on the first subscription. To do that, you need to subscribe within a non-reactive scope. To reach a non-reactive scope from within a reactive scope you need to use Tracker.nonreactive(function) http://docs.meteor.com/#/full/tracker_nonreactive Doing so will make you able to access the values you want without resubscribing. In this case, I would use a route method:

Note that this is untested code I threw together. Feel free to modify and tweak.

Router.route('/path/:param', function(){
    var self = this;
    var computation, subscription;
    Tracker.autorun(function(){
        if (!computation)
            computation = Tracker.currentComputation;
        if (!subscription)
            Tracker.nonreactive(function(){
                subscription = self.subscribe('subscription', /*reactive var here */);
                computation.invalidate();
            });
        if (subscription && subscription.ready()){
            self.render('templateName');
            self.subscribe('subscription', /*reactive var here */);
        }
    });
});

A little about what it's doing. This is making a nested computation for the route which can be rerun at will, with some global variables to keep track of the computation and the subscription which we don't want to deal with changing. We subscribe to the subscription twice, once in a non-reactive state where changes won't affect it. This is the one we use to calculate whether to render. We then render when that subscription is ready and at that point resubscribe with a reactive variable. Meteor is smart in that it recognizes the new subscription as the same as the old one, and will only update the minimongo record based on it. This allows for effectively seamless redraw. Finally there is the computation.invalidate which causes the internal computation to rerun now that this is a subscription (making the existence of the subscription reactive while the subscription itself is non reactive).

Upvotes: 0

Tomasz Lenarcik
Tomasz Lenarcik

Reputation: 4880

waitOn is called within a computation and invalidating it (e.g. when a Session variable changes) will cause your route controller to recompute everything. So basically, you should only be subscribing inside waitOn based on data that comes from this.params object. That's what it's designed for.

If you want another behavior and make your subscription parameters dependent on some Session variables, then it probably does not have anything to do with the router. In that case, you should probably use Deps.autorun pattern as you described in your answer.

Upvotes: 1

tomet
tomet

Reputation: 2556

Apparently, what I want is not possible. The solution I have found is as follows:

Instead of subscribing using waitOn, I subscribe in a Deps.autorun in the Template.rendered callback.

Upvotes: 0

Related Questions