Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(react): support routes without a path for notfound routes, fixes #…
  • Loading branch information
elylucas committed Jan 21, 2020
1 parent 1411d8a commit 2f8c13b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
2 changes: 1 addition & 1 deletion packages/react-router/src/ReactRouter/IonRouteData.ts
@@ -1,6 +1,6 @@
import { RouteProps, match } from 'react-router-dom';

export interface IonRouteData {
match: match<{ tab: string }> | null;
match: match | null;
childProps: RouteProps;
}
16 changes: 15 additions & 1 deletion packages/react-router/src/ReactRouter/Router.tsx
Expand Up @@ -255,12 +255,23 @@ export class RouteManager extends React.Component<RouteManagerProps, RouteManage
const views: ViewItem[] = [];
let activeId: string | undefined;
const ionRouterOutlet = React.Children.only(children) as React.ReactElement;
let foundMatch = false;
React.Children.forEach(ionRouterOutlet.props.children, (child: React.ReactElement) => {
const routeId = generateId();
this.routes[routeId] = child;
views.push(createViewItem(child, routeId, this.props.history.location));
});

if (!foundMatch) {
const notFoundRoute = views.find(r => {
// try to find a route that doesn't have a path or from prop, that will be our not found route
return !r.routeData.childProps.path && !r.routeData.childProps.from;
});
if (notFoundRoute) {
notFoundRoute.show = true;
}
}

this.registerViewStack(id, activeId, views, routerOutlet, this.props.location);

function createViewItem(child: React.ReactElement<any>, routeId: string, location: HistoryLocation) {
Expand Down Expand Up @@ -289,6 +300,9 @@ export class RouteManager extends React.Component<RouteManagerProps, RouteManage
if (match && view.isIonRoute) {
activeId = viewId;
}
if (!foundMatch && match) {
foundMatch = true;
}
return view;
}
}
Expand Down Expand Up @@ -360,7 +374,7 @@ export class RouteManager extends React.Component<RouteManagerProps, RouteManage
React.Children.forEach(ionRouterOutlet.props.children, (child: React.ReactElement) => {
for (const routeKey in this.routes) {
const route = this.routes[routeKey];
if (route.props.path === child.props.path) {
if (typeof route.props.path !== 'undefined' && route.props.path === (child.props.path || child.props.from)) {
this.routes[routeKey] = child;
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/react-router/src/ReactRouter/View.tsx
Expand Up @@ -65,6 +65,7 @@ export class View extends React.Component<ViewProps, {}> {
...value,
registerIonPage: this.registerIonPage.bind(this)
};

return (
<NavContext.Provider value={newProvider}>
{this.props.children}
Expand Down
39 changes: 24 additions & 15 deletions packages/react-router/src/ReactRouter/ViewStacks.ts
Expand Up @@ -13,7 +13,7 @@ export interface ViewStack {
* The holistic view of all the Routes configured for an application inside of an IonRouterOutlet.
*/
export class ViewStacks {
private viewStacks: { [key: string]: ViewStack | undefined } = {};
private viewStacks: { [key: string]: ViewStack | undefined; } = {};

get(key: string) {
return this.viewStacks[key];
Expand All @@ -31,25 +31,34 @@ export class ViewStacks {
delete this.viewStacks[key];
}

findViewInfoByLocation(location: HistoryLocation, viewKey?: string) {
findViewInfoByLocation(location: HistoryLocation, viewKey: string) {
let view: ViewItem<IonRouteData> | undefined;
let match: IonRouteData['match'] | null | undefined;
let viewStack: ViewStack | undefined;
if (viewKey) {
viewStack = this.viewStacks[viewKey];
if (viewStack) {
viewStack.views.some(matchView);

viewStack = this.viewStacks[viewKey];
if (viewStack) {
viewStack.views.some(matchView);

if (!view) {
viewStack.views.some(r => {
// try to find a route that doesn't have a path or from prop, that will be our not found route
if (!r.routeData.childProps.path && !r.routeData.childProps.from) {
match = {
path: location.pathname,
url: location.pathname,
isExact: true,
params: {}
};
view = r;
return true;
}
return false;
});
}
} else {
const keys = this.getKeys();
keys.some(key => {
viewStack = this.viewStacks[key];
return viewStack!.views.some(matchView);
});
}

const result = { view, viewStack, match };
return result;
return { view, viewStack, match };

function matchView(v: ViewItem) {
const matchProps = {
Expand All @@ -61,7 +70,7 @@ export class ViewStacks {
if (myMatch) {
view = v;
match = myMatch;
return view.location === location.pathname;
return true;
}
return false;
}
Expand Down

0 comments on commit 2f8c13b

Please sign in to comment.