Just playing around and attempting to port the Microscope example from Iron Router to Flow Router. I am trying to work on the “Load More” feature at the moment, and ran into an issue. Any time a ReactiveVar would get updated, this error message would appear in the console;
Error: You can't use reactive data sources like Session inside the '.subscriptions' method!
Note that for now, I am just using a ReactiveVar to control the page limit instead of reading from the query. But when the button gets clicked to increase the page limit, that error message gets displayed.
Now, I know that FlowRouter isn’t reactive like IronRouter by design, but I figured that since subscriptions support reactive values, this would be possible.
Should this be possible with FlowRouter? Am I doing something wrong? If this is expected behavior is, is there a pattern to use Flow Router and reactive subscriptions together?
I agree with Arunoda. I am migrating away from IronRouter because it allows you to do so much reactive stuff in the routes. One of the pros of FlowRouter is that it’s very simple, you hit a route and load a template. This makes the router layer very easy to maintain.
In a small app having reactive subs in the router seems like a great idea, but it has always come back to bite me sooner or later. The article @nxcong linked to is a far better way. I’m refactoring my subscriptions and reactive data out of the router and into the template level and it’s made debugging easier and has reduced bugs.
I’m going to try both template level subscriptions and keeping the state in the URL to see which one works better and feels nicer (at least for this example).
Maybe I’ll have an example worth showing off in the future!
Yea let us know how it works! Also, you can still store state in the URL when using template level subscriptions. I do this a lot to enable the user to bookmark the page or copy/paste the link and that allows everything to rebuild based on the URL.
Basically the route can have params or query params for the data your app needs (limit, offset, etc…) and when the top level template loads (let’s call it ‘FeedList’), it will look at the current params (using FlowRouter API) and then it will setup it’s subscription based on those params. To increase the limit you can update those params (with FlowRouter API) and the subscription will update itself reactively!
With this scenario your router is only responsible for loading your ‘FeedPage’ template and then your ‘FeedList’ child template can be responsible for changing the data it needs.
To illustrate how helpful this is in a more complex app, say your ‘FeedPage’ (imagine the Facebook feed if it helps) would have 3 child components… ‘FeedList’, ‘ChatList’, and ‘TrendingList’. Each of these have separate subscriptions and it’s very easy to see where the data is coming in from.
If you need further organization because your top level ‘FeedList’ template/script is getting too complex, you can create a parent template called ‘FeedDataContainer’ who’s only responsibility is fetching data and rendering it’s single child, the ‘FeedList’ template. It would pass this data down into ‘FeedList’.
This may be overkill on a small app but makes things more re-useable in a large app. (for instance if a ‘comment’ template get’s it’s data from a parent, not directly, it makes it easy to use this ‘comment’ in a feed item, photo item, etc… This is something i’ve learned from React but it works quite well in Blaze as well.
I hope you are trying to use the .subscriptions method in the flow-router. If so, try to send the parameters from the URL. If you can’t try to save it on normal variables.
If you really needs to use session variables. Use this inside Tracker.nonreactive