-
Notifications
You must be signed in to change notification settings - Fork 415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: does waitOn
actually wait for subscription to be ready?
#265
Comments
@cmather can probably give a good firm answer on this, but for now if you wrap the code in your call backs in an if(this.ready()) it will fix this issue for now. Router.map(function () {
this.route('hello', {
path: '/',
data: function() {
if(this.ready()){
console.log(s.ready());
}
},
waitOn: s
});
}); |
Yes, waitOn will wait the subscription to be ready. Right now, as 0.6 version, You could do something like this as you were with waitOn. I found this pattern a lot easier to reason about. this.route('postShow', {
path: '/posts/:slug',
//XXX before could be in form of array
before: function () {
// Use this.subscribe to subscribe whatever subscription you want for this route. If you want to wait for the subscription to be ready, then use .wait() method.
this.subscribe('post', this.params.slug).wait();
this.subscribe('all-posts');
},
data: function () {
return Posts.findOne({
slug: this.params.slug
});
}
} |
before could be array of functions. |
The above didn't work for me, it just stays loading forever. router.js
publish.js
I echoed this problem using controllers in #261, #38, and in this gist - https://gist.github.com/bryanaka/7253198 |
In your publish function return a cursor ( When you call This works because the |
@yubozhao if using internal router subscription:
then how to unsubscribe from it when data is no longer needed? And also, if "waitOn will wait the subscription" why it calls |
@nleush When you call the wait method, this.subscribe('post').wait() It acts as the router will wait on this subscription to be ready then go on its business. As far as unsubscribe, Meteor is taking care of that. You dont really need to do anything. And if you set some sorta of Session variable that you want to clean out, you can always use the unload hook this.route('post', {
before: [/* some functions you want to run in before hook*/],
data: function () {
/* find data and return them here */
},
unload: function () {
/* anything you want to do before it went on to different route. */
// for example
Session.set('postId', null); // clean up Session variables
}
}); It calls data before the wait() subscription is ready? Could you give me an example to look further? |
Maybe I'm doing something wrong but here it is: Router doesn't wait for |
@yubozhao how does Meteor actually know that subscription should be unsubscribed? |
That's because you didn't set |
@nleush
You probably have to look into Meteor source to found now more about it. It would be in the packages/livedata/livedata_connection.js file, I think. |
@nleush |
So... there was a lot of discussion on this, but the original issue (which I also witness) wasn't addressed. If I use the latest version of
Is this the intended logic? Did something change? |
For the previous question about how subscriptions get stopped automatically check out this video: @hellogerard, This behavior was changed a bit. In a previous version (on dev) the entire route would not run until the controller was in a ready state. This was changed to allow individual functions in the route (before hooks, action function, after functions) to decide what to do based on the ready state. I just checked and realized the setDataHook does not check for the ready state and it probably should. I'm also open to other suggestions for the right flow here. |
@cmather thanks for video! Very clear explanation. So as I understand, iron-router calls hooks and |
@cmather i'm having this problem too, and i think that running data hooks without waiting for subscriptions to be ready kinda defeats the whole purpose of the wait/waitOn mechanism. So I strongly vote for checking the ready state in setDataHooks, if it means that data and action hooks won't be called until the subscriptionsdare ready, even if loadingTemplate is not set (just leave the currently renderd templates until the new ones are ready to be rendered). Otherwise, this loadingTemplate dependency should be at least documented in the readme. |
@cmather Thanks for the clarification. I'm open to any flow, as long as it's documented. |
+1 for checking the ready state, or at least adding this to the available options on RouteController with default set to false. |
So if anyone reads this, I spent some time understanding the current logic around this issue. I think I have a handle on them. Note that where ever I say "block" below, I mean the route is stopped, but since it's reactive, it gets re-run once the data is ready. Pre
So in the current iron router, if you have a One thing tripping me up: I was having issues around Hopefully this helps someone. You'll need to set up iron router differently depending on if you want a loading indicator vs holding up the whole screen waiting for data vs etc. |
Hey @hellogerard, That's a pretty good summary of what's happening. I think what's needed in the short term is a check on the default action and on the setData hook to make sure everything is ready. I think those checks are currently missing. But the loadingTemplateHook checks the ready state to decide whether to show the loading template. Pull requests definitely welcome to update the hook behavior (lib/client/route_controller.js). |
Thanks @cmather. I'd love to take a crack at a PR, but, like you, I'm not sure what the best design here is. Need a balance between easy, out-of-the-box behavior, and flexibility to really customize route behavior. I'll think on it. Thanks for all your work. |
With help from @th0r and @hellogerard, solved with the following approach. See my comment on #287 for background. Use only Pass to
Wrap entire content of
I had some final bugs caused by urls to assets required by these templates. Check to be sure the urls still make sense within the path you've given the router for a particular view. |
The "must have" requirement for loadingTemplate doesn't make any sense, it should just stop() regardless of loadingTemplate presence. |
If the pattern is to wrap every data block in a this.ready() check, why not just have IronRouter do the check first? It seems silly to call the data hook before the route is actually ready. |
Hi @mrmowgli, I don't think wait on data is necessary for every route. For some page, I am not waiting for the data to be ready to load up the page. So, I think this design give me a lot of flexibility of how should pages behave. |
@yubozhao , I understand, but in that case why not use an before hook? Or if its so important for the hook to be called before the collections from waitOn are actually ready, why couldn't Iron Router have a final_data hook or something similar instead? |
IMHO if user calls |
After encountering this issue firsthand, I was able to get it working by experimenting with some of the recommended solutions above, but moreso by reading up on the new amendments to the Iron Router documentation section called Waiting on Subscriptions, found here: https://github.com/EventedMind/iron-router/blob/dev/DOCS.md#waiting-on-subscriptions-waiton Firstly, it is important to note that the waitOn: function () {
return Meteor.subscribe('campaigns_edit', this.params.uuid);
},
data: function () {
return Campaigns.findOne({uuid: this.params.uuid});
},
action: function () {
if (this.ready()) {
this.render();
}
} Thanks for all your help! |
I'm expecting
waitOn
will wait for subscription.ready() === true and then start getting data and render template. But in this example:https://github.com/nleush/iron-router-wait-test/blob/master/iron-router-wait-test.js#L22
Console output:
That means data and render runs first time when subscription not ready yet.
The text was updated successfully, but these errors were encountered: