app-route
app-route copied to clipboard
Pathname "/" matches "/:pattern"
Description
When using path (i.e. non-hash) routing and at the root domain (e.g. "http://localhost"), <carbon-route pattern="/:pattern">
becomes active and the data object becomes { pattern: '' }
(empty string mapped to pattern).
Expected outcome
The <carbon-route>
should not match.
Actual outcome
The <carbon-route>
matches and data is { pattern: '' }
.
Live Demo
(No demo since it's hard to make one with jsbin paths :( )
Steps to reproduce
<carbon-location route="{{route}}"></carbon-location>
<carbon-route
route="{{route}}"
pattern="/:pattern"
active="{{isActive}}"
data="{{data}}"></carbon-route>
Browsers Affected
All browsers
For me this is intended behavior. If this would not work, the selection of a home-page within an iron-pages
would not be possible and significantly degrades the developer experience using this element. Therefore I would vote to keep the current behavior as this is more intuitive.
You can avoid this match preceding another app-rote to math the "/". Something like:
<app-location route="{{route}}"></app-location>
<app-route
route="{{route}}"
pattern="/">
</app-route>
<app-route
route="{{route}}"
pattern="/:pattern"
active="{{isActive}}"
data="{{data}}">
</app-route>
This only happens with root path. If you are in the next situation this doesn't happen.
<app-route
route="{{route}}"
pattern="/:pattern"
active="{{isActive}}"
data="{{patterData}}"
tail="{{patternTail}}">
</app-route>
<app-route
route="{{patternTail}}"
pattern="/:pattern2"
active="{{isActive2}}"
data="{{data}}">
</app-route>
In this case we have this scenarios:
- localhost --> isActive === true & isActive2 === false
- localhost/ --> isActive === true & isActive2 === false
- localhost/path --> isActive === true & isActive2 === false
- localhost/path/ --> isActive === false & isActive2 === true
- localhost/path/path2 --> isActive === false & isActive2 === true
Just bumped into this and the inconsistency is bothering me.
I agree with @TimvdLippe that, on the root that is the intended behaviour you find in all frameworks. I.e.(using the example above by @jorgecasar):
-
http://localhost
andhttp://localhost/
: both should match (isActive === true
) andpatternData
should yield{pattern: ''}
But how is this different for nested routes? I would expect:
-
http://localhost/path
andhttp://localhost/path/
: both to match (isActive2 === true
) anddata
to yield{pattern2: ''}
But that is not the case. As @jorgecasar mentions, the second matches, the first doesn't. This is because app-location
(and window.location.pathname
underneath) is setting the route.path
to '/', but when using the tail
to pass the remaining path to the nested app-route
element, it's not doing the same (i.e. patternTail.route
is '' instead of '/').
How to achieve composition and isolation? I should be able to move a component into the root or within a nested path without issues.
I'm having this exact same issue and is driving me crazy. I can't be polluting my nested routes like that. I could potentially forget about one . Is it possible to do a regex inside the "pattern"? That way we could always do: /?:pattern
This thread is over a year old now. I wanted to post a possible workaround for the missing trailing slash issue, since it doesn't appear that this is of high priority.
<app-location route="{{route}}"></app-location>
<app-route route="{{route}}" pattern="/:page" tail="{{subroute}}"></app-route>
<app-route route="{{subroute}}" pattern="/:id" data="{{subrouteData}}"></app-route>
In your polymer element, setup an observer for subroute.path
. If it is an empty string, you can then modify the subrouteData.id
property.
observers: [
'_onSubroute(subroute.path)'
],
_onSubroute: function(subroutePath) {
if(subroutePath === '') {
this.set('subrouteData.id', '');
}
}
@cloudily Thanks for the workaround, I"ll keep this around ;)