Skip to content
This repository has been archived by the owner on Dec 19, 2024. It is now read-only.

Question: Who should handle 404 pages? #126

Open
ymaz opened this issue Jul 5, 2016 · 11 comments
Open

Question: Who should handle 404 pages? #126

ymaz opened this issue Jul 5, 2016 · 11 comments

Comments

@ymaz
Copy link

ymaz commented Jul 5, 2016

Hi, it's not a issue at all, it's more just a questing/best practices manual/discussion.

So, who should handle 404 page in Polymer app, which using <app-route> for the routing?

I mean, when user typed something incorrect which is not relevant to any page/view. Which element should be responsible for redirect?

For example, I'm using combo <app-route> + <iron-pages>. I've spotted that <iron-pages> support fallbackSelection attr for fallback view.

Okay, theoretically, i can do like this:

    <iron-pages role="main" selected="[[page]]" attr-for-selected="name" selected-attribute="visible" fallback-selection="404">
      <!-- home view -->
      <shop-home name="home" categories="[[categories]]"></shop-home>
      <!-- list view of items in a category -->
      <shop-list name="list" route="[[subroute]]" offline="[[offline]]"></shop-list>
      <!-- detail view of one item -->
      <shop-detail name="detail" route="[[subroute]]" offline="[[offline]]"></shop-detail>
      <!-- 404 page view -->
      <shop-404page name="404"></shop-404page>
    </iron-pages>

This solution will work okay for top level navigation, like /list, /details
but what if something goes wrong on the second level?
Example /list/blabla and etc.?

How I should handle this cases?
Or i need to write some kind of _pageResolver(page) method which will receive the page string, and tries to find that page in already pre-defined router-config object/array, and after that passed the value into <iron-pages> otherwise set to 404?

Many thanks and please feel free to share you opinion regarding that.

@TimvdLippe
Copy link

In general if a sub-route selector fails to match, the element where the selector is defined should handle the 404. So you can use fallback-selection in a selector on a sub-page which probably shows the same 404-page. However, you are not limited to just this page. If you want to display other content, you can too.

@ymaz
Copy link
Author

ymaz commented Jul 5, 2016

@TimvdLippe, thanks for your opinion.

@ymaz
Copy link
Author

ymaz commented Jul 6, 2016

@TimvdLippe one more thing, which i didn't get

so, i've have a my-app with <app-route> for top level views/pages.
Then each view or page has it's own <app-route> for sub-pages (second level).
So, on each sub-page element you would like to check if sub-route is matching or not and then somehow redirect for top level <app-route> 404 page view?

I like the idea with decentralized routing items, but i think we should one point to handle misleading pages.

@TimvdLippe
Copy link

@ymaz there are no redirects with the componentized router. Therefore each selector handles the 404 on its own, without notifying its parent.

This allows you to define a specific 404 handler for each case, as you might want to propagate different information to your user depending on the sub-route. E.g. "This user could not be found" on a users page, or a "This setting does not exist" when you are in a settings view.

That said, we might be able to fire an event when a fallback selection is triggered. Then in your root app element you listen for this event and act accordingly. What do you think of updating iron-selector to fire this event @rictic @bicknellr ?

@ymaz
Copy link
Author

ymaz commented Jul 6, 2016

@TimvdLippe

we might be able to fire an event when a fallback selection is triggered.

completely agree!

there are no redirects with the componentized router. Therefore each selector handles the 404 on its own, without notifying its parent.

Okay, but if we actually need to have some logic, like if /list/item1, where item1 not found (nothing to display, not matching, etc.), then show parent /list view to avoid show white screen or something for the user.

@ymaz
Copy link
Author

ymaz commented Jul 8, 2016

So, actually right now i'm understand how to make 404 page for top level nav via <iron-pages>
but didn't get how to handle this for sub items (second level of nav), how to show for example the same 404 view, if sub-page is not valid(found).

@ghost
Copy link

ghost commented Jul 30, 2016

I am struggling with the same issue. In my top level app element, I have app-route with iron-pages and am using fallback-selector. If the section is missing or invalid, it selects account and updates the url.

pk-app.html

    <app-location route="{{route}}"></app-location>

    <app-route
        route="{{route}}"
        pattern="/:module"
        data="{{routeData}}"
        tail="{{routeTail}}">
    </app-route>

    <iron-pages role="main" selected="{{routeData.module}}" attr-for-selected="name" fallback-selection="account">
      <pk-account-master name="account" route="{{routeTail}}"></pk-account-master>
      <pk-member-master name="member" route="{{routeTail}}"></pk-member-master>
    </iron-pages>

I am passing in the route tail to the child elements where I also have an app-route with iron-pages and am using fallback-selector. In the nested element however, although fallback-selector is working, it is not updating the URL.

    <app-route
        route="{{route}}"
        pattern="/:page"
        data="{{routeData}}">
    </app-route>

    <iron-pages role="main" selected="{{routeData.page}}" attr-for-selected="name" fallback-selection="login">
      <pk-account-login name="login"></pk-account-login>
    </iron-pages>

UPDATE: Just realized there is another problem as well. If you have multiple nested sub-elements with app-route and iron-pages with a fallback selector, they all stomp on each other until you get a maximum call stack size exceeded because they are all trying to update the location with their default. Fallback selector is not a working strategy for default or invalid routes if you have multiple nested app-routes with iron-pages.

@rictic
Copy link
Contributor

rictic commented Jul 31, 2016

Can you give a demo of this failure with nested app-routes and iron-pages @chrismbeckett? Here's a jsbin to start: https://jsbin.com/hirore/edit?html,output

The issue with them stomping all over each other shouldn't happen unless different routable components each mutually believe that the others' urls are unacceptable.

@TimvdLippe
Copy link

Little reminder for myself: to have 1 entry point for handling 403's we could fire an event in iron-selector when a fallback-selection is triggered. You can listen for this event in your app element and handle it there. WDYT?

@ghost
Copy link

ghost commented Aug 9, 2016

@TimvdLippe The Iron-Selector has the iron-activate event that is supposed to support aborting a selection. The fix for multiple nexted iron-pages blocks with fallback selectors would be to wire up the iron-activate event and abort if the parent route segment doesn't match your sub-route block (e.g. ignore login, register, etc., if parent segment isn't account). This didn't work for me - the iron-activate was not firing for fallback selectors. I think simply making the iron-activate event fire properly for fallback selector could solve the problem.

@TimvdLippe
Copy link

I have created a new pull request on iron-selector to facilitate a monolithic router structure regarding 404 handling here: PolymerElements/iron-selector#137

An example usage of this event can be found in this diff: https://github.com/TimvdLippe/polymer-lazy-application/compare/monolithic-router?expand=1#diff-8177f8e50fd6fc8e66434f5c76f38d98R45
Here you can listen for the event and based on that handle just one 404 page.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants