Skip to content

Commit

Permalink
fix: make route matching more explicit (#25)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

Removes usage of `/**` pattern for parent and wildcard routes

BEFORE:

```html
  <route path="/books/**"></route>
```

AFTER:

```html
  <route path="/books" [exact]="false">
```
  • Loading branch information
brandonroberts committed Jul 21, 2020
1 parent d656ce0 commit 3b8716b
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 106 deletions.
57 changes: 27 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import { RoutingModule } from 'angular-routing';
@NgModule({
imports: [
// ... other imports
RoutingModule.forRoot()
]
RoutingModule.forRoot(),
],
})
export class AppModule {}
```
Expand All @@ -40,18 +40,18 @@ import { RoutingModule } from 'angular-routing';
@NgModule({
imports: [
// ... other imports
RoutingModule
]
RoutingModule,
],
})
export class FeatureModule {}
```

After your components are registered, use the `Router` and `Route` components to register some routes.
After your components are registered, use the `Router` and `Route` components to register some routes.

```html
<router>
<!-- For nested routes use suffix '/**' -->
<route path="/blog/**">
<!-- For nested routes use exact: false -->
<route path="/blog" [exact]="false">
<app-blog *routeComponent></app-blog>
</route>
<route path="/posts/:postId">
Expand All @@ -60,9 +60,8 @@ After your components are registered, use the `Router` and `Route` components to
<route path="/about">
<app-about *routeComponent></app-about>
</route>
<route path="/" redirectTo="/blog">
</route>
<route path="**">
<route path="/" redirectTo="/blog"> </route>
<route path="/" [exact]="false">
<app-page-not-found *routeComponent></app-page-not-found>
</route>
</router>
Expand All @@ -85,7 +84,9 @@ To add classes to links that match the current URL path, use the `linkActive` di
```html
<a linkTo="/" linkActive="active">Home</a>
<a linkTo="/about" linkActive="active">About</a>
<a linkTo="/blog" linkActive="active" [activeOptions]="{ exact: false }">Blog</a>
<a linkTo="/blog" linkActive="active" [activeOptions]="{ exact: false }"
>Blog</a
>
```

## Using the Router service
Expand Down Expand Up @@ -113,7 +114,7 @@ export class MyComponent {

## Using Route Params

To get the route params, inject the `RouteParams` observable. Provide a type for the shape of the route params object.
To get the route params, inject the `RouteParams` observable. Provide a type for the shape of the route params object.

```ts
import { Component } from '@angular/core';
Expand All @@ -133,7 +134,7 @@ export class MyComponent {

## Using Query Params

To get the route params, inject the `QueryParams` observable. Provide a type for the shape of the query params object.
To get the route params, inject the `QueryParams` observable. Provide a type for the shape of the query params object.

```ts
import { Component } from '@angular/core';
Expand Down Expand Up @@ -161,15 +162,14 @@ import { Component } from '@angular/core';
@Component({
template: `
<router>
<route path="/lazy/**" [load]="modules.lazy">
</route>
<route path="/lazy" [exact]="false" [load]="modules.lazy"> </route>
</router>
`
`,
})
export class MyComponent {
modules = {
lazy: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}
lazy: () => import('./lazy/lazy.module').then((m) => m.LazyModule),
};
}
```

Expand All @@ -185,20 +185,18 @@ import { ModuleWithRoute } from 'angular-routing';
<route path="/">
<app-lazy *routeComponent></app-lazy>
</route>
</router>
`
<route path="/" [exact]="false" redirectTo="/404"> </route>
</router>
`,
})
export class LazyRouteComponent { }
export class LazyRouteComponent {}
```

Implement the `ModuleWithRoute` interface for the route component to render after the module is loaded.

```ts
@NgModule({
declarations: [
LazyRouteComponent,
LazyComponent
]
declarations: [LazyRouteComponent, LazyComponent],
})
export class LazyModule implements ModuleWithRoute {
routeComponent = LazyRouteComponent;
Expand All @@ -215,14 +213,13 @@ import { Component } from '@angular/core';
@Component({
template: `
<router>
<route path="/lazy" [load]="components.lazy">
</route>
<route path="/lazy" [load]="components.lazy"> </route>
</router>
`
`,
})
export class MyComponent {
components = {
lazy: () => import('./lazy/lazy.component').then(m => m.LazyComponent)
}
lazy: () => import('./lazy/lazy.component').then((m) => m.LazyComponent),
};
}
```
9 changes: 5 additions & 4 deletions apps/example-app/src/app/books/books.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ import * as fromBooks from '@example-app/books/reducers';
<route path="/">
<bc-collection-page *routeComponent></bc-collection-page>
</route>
<route path="/" [exact]="false" redirectTo="/404"> </route>
</router>
`
`,
})
export class BooksComponent {
loggedIn$ = this.authGuard.canActivate();
Expand All @@ -54,15 +55,15 @@ export const COMPONENTS = [
BookPreviewComponent,
BookPreviewListComponent,
BookSearchComponent,
BooksComponent
BooksComponent,
];

export const CONTAINERS = [
FindBookPageComponent,
ViewBookPageComponent,
SelectedBookPageComponent,
CollectionPageComponent,
BooksComponent
BooksComponent,
];

@NgModule({
Expand Down Expand Up @@ -90,7 +91,7 @@ export const CONTAINERS = [
EffectsModule.forFeature([BookEffects, CollectionEffects]),
],
declarations: [COMPONENTS, CONTAINERS],
entryComponents: [BooksComponent]
entryComponents: [BooksComponent],
})
export class BooksModule implements ModuleWithRoute {
routeComponent = BooksComponent;
Expand Down
18 changes: 13 additions & 5 deletions apps/example-app/src/app/core/containers/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ import { LayoutActions } from '@example-app/core/actions';
>
Browse Books
</bc-nav-item>
<bc-nav-item
(navigate)="closeSidenav()"
*ngIf="loggedIn$ | async"
linkTo="/books/find/bad"
icon="search"
hint="Find your next book!"
>
Browse Books 404
</bc-nav-item>
<bc-nav-item (navigate)="closeSidenav()" *ngIf="!(loggedIn$ | async)">
Sign In
</bc-nav-item>
Expand All @@ -43,13 +52,12 @@ import { LayoutActions } from '@example-app/core/actions';
</bc-toolbar>
<router>
<route path="/books/**" [load]="components.books"></route>
<route path="/books" [exact]="false" [load]="components.books"></route>
<route path="/login">
<bc-login-page *routeComponent></bc-login-page>
</route>
<route path="/" redirectTo="/books">
</route>
<route path="**">
<route path="/" redirectTo="/books"> </route>
<route path="/" [exact]="false">
<bc-not-found-page *routeComponent></bc-not-found-page>
</route>
</router>
Expand All @@ -58,7 +66,7 @@ import { LayoutActions } from '@example-app/core/actions';
})
export class AppComponent {
components = {
books: () => import('../../books/books.module').then(m => m.BooksModule)
books: () => import('../../books/books.module').then((m) => m.BooksModule),
};
showSidenav$: Observable<boolean>;
loggedIn$: Observable<boolean>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Router } from 'angular-routing';

@Component({
selector: 'bc-not-found-page',
Expand All @@ -10,7 +11,7 @@ import { Component, ChangeDetectionStrategy } from '@angular/core';
<p>Hey! It looks like this page doesn't exist yet.</p>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary" linkTo="/">
<button mat-raised-button color="primary" (click)="goHome()">
Take Me Home
</button>
</mat-card-actions>
Expand All @@ -24,4 +25,10 @@ import { Component, ChangeDetectionStrategy } from '@angular/core';
`,
],
})
export class NotFoundPageComponent {}
export class NotFoundPageComponent {
constructor(private router: Router) {}

goHome() {
this.router.go('/');
}
}
56 changes: 27 additions & 29 deletions libs/angular-routing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import { RoutingModule } from 'angular-routing';
@NgModule({
imports: [
// ... other imports
RoutingModule.forRoot()
]
RoutingModule.forRoot(),
],
})
export class AppModule {}
```
Expand All @@ -40,17 +40,18 @@ import { RoutingModule } from 'angular-routing';
@NgModule({
imports: [
// ... other imports
RoutingModule
]
RoutingModule,
],
})
export class FeatureModule {}
```

After your components are registered, use the `Router` and `Route` components to register some routes.
After your components are registered, use the `Router` and `Route` components to register some routes.

```html
<router>
<route path="/blog/**">
<!-- For nested routes use exact: false -->
<route path="/blog" [exact]="false">
<app-blog *routeComponent></app-blog>
</route>
<route path="/posts/:postId">
Expand All @@ -59,9 +60,8 @@ After your components are registered, use the `Router` and `Route` components to
<route path="/about">
<app-about *routeComponent></app-about>
</route>
<route path="/" redirectTo="/blog">
</route>
<route path="**">
<route path="/" redirectTo="/blog"> </route>
<route path="/" [exact]="false">
<app-page-not-found *routeComponent></app-page-not-found>
</route>
</router>
Expand All @@ -84,7 +84,9 @@ To add classes to links that match the current URL path, use the `linkActive` di
```html
<a linkTo="/" linkActive="active">Home</a>
<a linkTo="/about" linkActive="active">About</a>
<a linkTo="/blog" linkActive="active">Blog</a>
<a linkTo="/blog" linkActive="active" [activeOptions]="{ exact: false }"
>Blog</a
>
```

## Using the Router service
Expand Down Expand Up @@ -112,7 +114,7 @@ export class MyComponent {

## Using Route Params

To get the route params, inject the `RouteParams` observable. Provide a type for the shape of the route params object.
To get the route params, inject the `RouteParams` observable. Provide a type for the shape of the route params object.

```ts
import { Component } from '@angular/core';
Expand All @@ -132,7 +134,7 @@ export class MyComponent {

## Using Query Params

To get the route params, inject the `QueryParams` observable. Provide a type for the shape of the query params object.
To get the route params, inject the `QueryParams` observable. Provide a type for the shape of the query params object.

```ts
import { Component } from '@angular/core';
Expand Down Expand Up @@ -160,15 +162,14 @@ import { Component } from '@angular/core';
@Component({
template: `
<router>
<route path="/lazy/**" [load]="modules.lazy">
</route>
<route path="/lazy" [exact]="false" [load]="modules.lazy"> </route>
</router>
`
`,
})
export class MyComponent {
modules = {
lazy: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}
lazy: () => import('./lazy/lazy.module').then((m) => m.LazyModule),
};
}
```

Expand All @@ -184,20 +185,18 @@ import { ModuleWithRoute } from 'angular-routing';
<route path="/">
<app-lazy *routeComponent></app-lazy>
</route>
</router>
`
<route path="/" [exact]="false" redirectTo="/404"> </route>
</router>
`,
})
export class LazyRouteComponent { }
export class LazyRouteComponent {}
```

Implement the `ModuleWithRoute` interface for the route component to render after the module is loaded.

```ts
@NgModule({
declarations: [
LazyRouteComponent,
LazyComponent
]
declarations: [LazyRouteComponent, LazyComponent],
})
export class LazyModule implements ModuleWithRoute {
routeComponent = LazyRouteComponent;
Expand All @@ -214,14 +213,13 @@ import { Component } from '@angular/core';
@Component({
template: `
<router>
<route path="/lazy" [load]="components.lazy">
</route>
<route path="/lazy" [load]="components.lazy"> </route>
</router>
`
`,
})
export class MyComponent {
components = {
lazy: () => import('./lazy/lazy.component').then(m => m.LazyComponent)
}
lazy: () => import('./lazy/lazy.component').then((m) => m.LazyComponent),
};
}
```

0 comments on commit 3b8716b

Please sign in to comment.