FlowRouter 2.0 & the Meteor Routing Guide


#1

Hi,

Yesterday, we’ve released FlowRouter 2.0 :smile:
I should thank everyone involved with FlowRouter and who’ve helped us.

We also released a guide called the Meteor Routing Guide.
That’ll take answer a lot of questions regarding FlowRouter way of doing things.

For example, template level auth handling and subscription management.

We also released, a few more projects related to FlowRouter.

Enjoiy!


#2

I was waiting for this to switch from Iron Router. Thanks a lot for your work @arunoda :wink:


#3

All hail the mighty Arunoda!


#4

I’m glad I no longer have to recommend something that starts with meteorhacks anymore :stuck_out_tongue:


#5

Just a heads up, in React I think it is a best practice to wrap JSX in parentheses, like so:

BlogHome = React.createClass({
  render() {
    return (
      <div>
        <p>This is the home page of our blog</p>
        <p>
          <a href="/hello-world">See Hello World Post</a>
        </p>
      </div>;
    )
  }
});

#6

Thanks for the advice. I’ll follow this.


#7

As always incredible stuff @arunoda thanks for sharing!


#8

Thanks arunoda for your work.

I’m excited to check these out!

Edit:

Btw, this is great news!

FlowRouter 1.x comes with its own subscription registration API. It’s much better than managing subscriptions at the router level. Anyway, we are removing it in 3.x.


#9

Hey @arunoda,

I didn’t see this in the migration guide: After installing FR2, the first argument passed to the action function no longer contains the query parameters. I used to be able to do params.query.id where params is arg1 to action. The guide does mention something similar for the FlowRouter object methods, though.

The query params seems to be the second argument to the action function now.

If this was in FR1, and I was using an old version, my mistake. Thought I should mention it just in case, though.

Thanks!


#10

Can I ask why is subscription mgmt in the router considered an anti-pattern?
I am not trolling, I think I must be missing the point. I am looking to understand why.

The points you raised I have never had an issue with with my apps (maybe I’ve just not noticed).
To be honest I don’t quite understand the tracker autorun means, is that bad?
I’ve not had reactivity issues, but I don’t really have anything reactive in my subscriptions - the user subscribes to their data and unless they log out that subscription just updates with their data…
The point on “loading messages” hasn’t been an issue, I simply defined a global helper which checked the subs.
From that I could toggle a loading message… simple enough.

// subReady - true/false for subscriptions being ready
Template.registerHelper('_subReady', function(subName) {
  if(subName) {
    return FlowRouter.subsReady(subName);
  } else {
    return FlowRouter.subsReady();
  }
});

I find great utility in grouping routes with flowrouter v1.
With that grouping I can define my subscriptions to the group.
If I had to do it on the template level I would be repeating myself with each template in that group?

Am I missing something??? To me it seems that the router is just as appropriate for sub mgmt as templates are…

edit:
as always thanks for the awesome contribution with v2 :smile:
I am looking forward to updating my apps with it :thumbsup:


Question to MDG: Building routing into core
#11

Two problems that result from doing subscriptions and data management in the route:

  1. Showing a loading screen for the whole page at once, instead of per-component. The best thing to do is to show as much of the page as possible immediately, and only have loading indicators inside components which are actually loading new data. Iron router convinced everyone to basically show a loader for every since page in the app, which means you lose most of the benefits of having a client-side app in the first place.
  2. Having to specify the data you are loading far away from the components which use the data. It’s easy to add a new component to your page and forget to add the data loading to the router, or the other way around where you load a bunch of data in the router that you actually aren’t using anywhere on the page.

#12

The subscription is the middleman between the view and the data. I don’t want my view to change because the middleman changed. I want it to change only when the data changed.

The way I think about it is, you want the granularity of data to be as close to the granularity of rendering as possible. If you get new data, only re-render the html that depends on the new data. It’s hard to do that with reactive route level subs. For sending necessary initialization information to the client (e.g. user profile, or user notification info that is not dep. on routes) imho it’s better to do that outside of routes too because that’s global and simply depends on if they are a connection client or not; no route level granularity.

Edit:

By doing things at route level, you lose all the specificity that you would have had at the view level.


#13

Actually, it was mentioned at the end. Very last line.


#14

You mean this?

Earlier, you can access query params with FlowRouter.current().params.query. But, now you can’t do that. Use FlowRouter.current().queryParams instead.

I didn’t know they boiled down to same implementation:

//in route
action: function(params){
  params.query // no longer supported
  //where is queryParams? 
}

I just did a simple console(arguments) to see that you changed it to be the second argument.


#15

Actually, queryParams second argument was there.


#16

Ah i see! ok well that makes sense, I guess i just got used to using the first arg in the old API :wink: - didn’t even know it was provided as a second argument. Maybe I did, but forgot since i never used it.


#17

Even we used it. I don’t remember where we used for that API. May be from NodeJS express I think.


#18

It’s a great idea for a small app (like the leaderboard example). However it’s easier to reason about data flowing in a large app when you break it into many small pieces.

Think of the facebook app and it’s chat sidebar. You could have the top-level chat-sidebar template subscribe to the chats and if you want to adjust the chats subscription… you can drill right down into it (Facebook also uses a template called a ‘container’ to let the dev know it’s handling data).

This moves several hundred lines of code in a router action down to each component that ‘owns’ the part of the app. Everything the sidebar needs is right there (not spread out across other parts of the app).


Flow router: this.autorun vs subscription in router
#19

Thanks everyone for the answers.

I guess I didn’t see it from that point of view because I have only built simple single page applications which don’t have multiple templates rendered on the screen. Also in my apps I usually only have two or three collections which get subscribed to.

I might try to refactor my code a bit to try and move that logic out of the router and into the template to see how it might work. To be honest, I never tried it, just thought about it.


#20

I think your code can be reduced a bit:

Template.registerHelper('_subsReady', FlowRouter.subsReady);