Router waitOn waits on subscription on every render
Asked Answered
D

2

5

I have a route with a waitOn hook that returns a Meteor.subscribe. Every time the route is triggered, I see the spinner from my loadingTemplate briefly before seeing the actual data.

I would have thought that I only had to wait on the subscription to be downloaded once, namely the first time?

If I'm doing it wrong, please suggest a better way.

Danit answered 22/1, 2014 at 18:15 Comment(0)
M
7

Have a look at the last comments on this issue. Chris explains that the subscriptions initiated by your router will be stopped once you navigate away from the route that activated them. This means that changing routes causes your subscriptions to continually start and stop, which explains the behavior you are seeing. Here are some options:

Start the subscription outside of the router

Putting subscriptions into your router has the benefit of delaying the subscription until it's needed. But you also pay the penalty of having not having the data before the route is run. Consider activating some of your subscriptions outside of the router like so:

Tracker.autorun(function() {
  if (Meteor.user()) {
    Meteor.subscribe('posts');
  }
});

Don't wait on the subscription

You could add your subscriptions to your route's before hook. See the example here. You get the benefit of subscribing when you need the data but not having to wait. The downside is that you'll probably need to add some guards to your code to protect against your data not being loaded yet.

Use a subscription manager

Have at look at subs-manager (documentation here). It's a package built to help with this exact problem. We use it in production and it really helps increase our subscription reuse between routes. One word of advice - the cacheLimit and expireIn have pretty conservative defaults, so if you have a lot of shared subscriptions you should consider increasing these.

Mathura answered 22/1, 2014 at 18:57 Comment(6)
Thanks for the answer and especially the link to the Iron-Router issue. If I create my subscription outside a waitOn hook (i.e. globally), how can I make sure the loadingTemplate is displayed, in the case route is called before the subscription has finished its first load?Danit
I'm suggesting you don't show your loadingTemplate in this case (since that's what you were trying to avoid in the first place). Instead, program defensively (see the 'guards' link above) and assume the data may not be there.Mathura
Fair enough. Another useful answer has been posted for the Iron-Router issue. Updated your answer with it. Thanks.Danit
The edit got rejected before I could look at it. Maybe just post the link in a commend so others can see it.Mathura
I have posted this as a new answer. Thanks again.Danit
This answer, was so helpful!! A lot of tutorials show waitOn subscribes... but it just breaks routing sometimes.Girlhood
D
1

An alternative answer to the accepted one was posted by mizzao as a comment to this issue under Iron-Router:

as long as the subscription is hit before the route loads, you can pass it to the router to wait on. I usually put all of my subscriptions - including autorun ones and router-loaded ones - into one file, and give the array of relevant ones to wait on. This is okay even if the global subscriptions change as long as they are stored back in the file's closure.

Danit answered 26/1, 2014 at 16:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.