0

More often than not, in a project, certain routes are a requirement, not a developer choice. That said, I agree to those routes too, in the detriment of query params (so called GET variables in php or other server-side languages).

There is a similar question here, however it is a scenario more simple than this one and it doesn't mention anything about solving the "optional" route params order. Nor does it treat a case when we need to have more than one or two "optional" route params (like when you filter the content for various things). It's only about one single "optional" route param. I keep using quotes because, as far as I know, by default there is no such thing as an "optional route parameter", as long as the only way to achieve this is to fake it (as in declaring all possible routes, with and without that param).

For example, as per project requirements, routes need to look like this:

/videos
/videos/categories/cat1_cat2
/videos/tags/tag1_tag2
/videos/categories/cat1_cat2/tags/tag1_tag2
OR
/videos/tags/tag1_tag2/categories/cat1_cat2

NOT like this:

/videos?categories=cat1_cat2&tags=tag1_tag2

Ok, the OR in the routes example above is my own, not a requirement. Because, even if in this scenario it is not the case (we wouldn't want to allow google or other search engine any chance to see the same content across different routes), still - in other cases - order doesn't matter. And, in those cases, it would be easier for the developer to simply not care about the order in which he/she stacks the filters when generating the route links. By "filter" I'm referring to a segment group such as /categories/:categories.

Putting the OR aside, at least the rest is a very common case, in fact all projects I've been involved in had filtering/sorting routes like this, not with query params.

So, having this limitation with angular's router, how would one go about the needed routes?

Sure, off the top of my head, I would think about this kind of setup:

[
  { path: '/videos/categories/:categories/tags/:tags', component: VideosComponent },
  { path: '/videos/categories/:categories', component: VideosComponent },
  { path: '/videos/tags/:tags', component: VideosComponent },
  { path: '/videos', component: VideosComponent }
]

Or maybe using child routes, defining them in a separate file so we won't clutter the main app routes with so much configuration in one place.

SO the above configuration of routes has obvious limitations:

  1. In the example above we only have up to 2 filters applied (categories and tags). This would be way too cumbersome if we had 4 or 5 filters. In case of 5 filters for example, we would need to define routes to combine any 1 filter, any 2 filters, any 3 filters, any 4 filters and all 5 filters. Also add pagination to that... and it would be routing configuration hell. I mean, for each of the above routes, add the fact that we may or may not also have /page/:page (we don't want /page/1 in the url, we only want to have /page in the url starting with page 2). This simply doubles all the above routes. Maintaining this route configuration has just become a separate project on it's own.
  2. As per the above route configuration, we can only stack segments in the url in a certain order: categories first, tags second. Sure, we might fix this by setting all the possible combinations in the configuration of the routes (having both /categories/:categories/tags/:tags and /tags/:tags/categories/:categories), which would be a pain to configure when we have more than 2 filters. It's just way too complicated to maintain. It would be more useful if the router would simply recognize /categories/cat1_cat2 no matter the placement of this segment group among the other segments/segment groups in the url. Sure, this would mean that the configuration would look different from what it is now, because we can also have "single" segments in the url, not only in pairs. But this is something they should have thought about way back, before they've even started to develop the router.

I can't believe that, when building the angular router, they didn't think about this (very common) scenario and offer some kind of helper in order to achieve this kind of customization. Is there something I'm missing? Does the router in fact offer a way to customize something like this, but no one got into that in any tutorial I've happen to see?

Community
  • 1
  • 1
MrCroft
  • 3,049
  • 2
  • 34
  • 50
  • With everything going to `VideoComponent`, the `tags` and `categories` parameters look like exactly what query-string parameters are for: optional arguments to the component. I think the designers did consider your case and decided that optional path parameters added too much complexity to the path parsing. The only way I can see to do it's the multiple-routes solution you have. – Todd Knarr Jul 28 '16 at 21:33
  • There are very few sites that I've seen to make use of query params for filtering. Most sites I've seen use routing for filtering the content on a page. I don't know the reason behind this, maybe SEO? Maybe google likes `/tags/tag1_tag2` better than `?tags=tag1_tag2`? I have no clue why, maybe I could ask my colleagues when going back from vacation. But added complexity or not, it seems that this scenario is used by the vast majority. Seems to be THE way of doing it... or a best practice. – MrCroft Jul 28 '16 at 22:01
  • In Rails and the like, yes. They allow route globbing where the entirety of the portion that matches the wildcarded item ends up as the value of the parameter. Angular only has a more limited "anything that didn't match another route" form. I suspect the use of the path to include parameters comes from CGI where you can get the tail end of the path separately from the part used to determine the destination. I always saw query-string parameters as more natural for specifying filter values. – Todd Knarr Jul 28 '16 at 23:55

0 Answers0