Skip to content

Commit 3b8716b

Browse files
fix: make route matching more explicit (#25)
BREAKING CHANGE: Removes usage of `/**` pattern for parent and wildcard routes BEFORE: ```html <route path="/books/**"></route> ``` AFTER: ```html <route path="/books" [exact]="false"> ```
1 parent d656ce0 commit 3b8716b

File tree

8 files changed

+132
-106
lines changed

8 files changed

+132
-106
lines changed

README.md

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import { RoutingModule } from 'angular-routing';
2626
@NgModule({
2727
imports: [
2828
// ... other imports
29-
RoutingModule.forRoot()
30-
]
29+
RoutingModule.forRoot(),
30+
],
3131
})
3232
export class AppModule {}
3333
```
@@ -40,18 +40,18 @@ import { RoutingModule } from 'angular-routing';
4040
@NgModule({
4141
imports: [
4242
// ... other imports
43-
RoutingModule
44-
]
43+
RoutingModule,
44+
],
4545
})
4646
export class FeatureModule {}
4747
```
4848

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

5151
```html
5252
<router>
53-
<!-- For nested routes use suffix '/**' -->
54-
<route path="/blog/**">
53+
<!-- For nested routes use exact: false -->
54+
<route path="/blog" [exact]="false">
5555
<app-blog *routeComponent></app-blog>
5656
</route>
5757
<route path="/posts/:postId">
@@ -60,9 +60,8 @@ After your components are registered, use the `Router` and `Route` components to
6060
<route path="/about">
6161
<app-about *routeComponent></app-about>
6262
</route>
63-
<route path="/" redirectTo="/blog">
64-
</route>
65-
<route path="**">
63+
<route path="/" redirectTo="/blog"> </route>
64+
<route path="/" [exact]="false">
6665
<app-page-not-found *routeComponent></app-page-not-found>
6766
</route>
6867
</router>
@@ -85,7 +84,9 @@ To add classes to links that match the current URL path, use the `linkActive` di
8584
```html
8685
<a linkTo="/" linkActive="active">Home</a>
8786
<a linkTo="/about" linkActive="active">About</a>
88-
<a linkTo="/blog" linkActive="active" [activeOptions]="{ exact: false }">Blog</a>
87+
<a linkTo="/blog" linkActive="active" [activeOptions]="{ exact: false }"
88+
>Blog</a
89+
>
8990
```
9091

9192
## Using the Router service
@@ -113,7 +114,7 @@ export class MyComponent {
113114

114115
## Using Route Params
115116

116-
To get the route params, inject the `RouteParams` observable. Provide a type for the shape of the route params object.
117+
To get the route params, inject the `RouteParams` observable. Provide a type for the shape of the route params object.
117118

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

134135
## Using Query Params
135136

136-
To get the route params, inject the `QueryParams` observable. Provide a type for the shape of the query params object.
137+
To get the route params, inject the `QueryParams` observable. Provide a type for the shape of the query params object.
137138

138139
```ts
139140
import { Component } from '@angular/core';
@@ -161,15 +162,14 @@ import { Component } from '@angular/core';
161162
@Component({
162163
template: `
163164
<router>
164-
<route path="/lazy/**" [load]="modules.lazy">
165-
</route>
165+
<route path="/lazy" [exact]="false" [load]="modules.lazy"> </route>
166166
</router>
167-
`
167+
`,
168168
})
169169
export class MyComponent {
170170
modules = {
171-
lazy: () => import('./lazy/lazy.module').then(m => m.LazyModule)
172-
}
171+
lazy: () => import('./lazy/lazy.module').then((m) => m.LazyModule),
172+
};
173173
}
174174
```
175175

@@ -185,20 +185,18 @@ import { ModuleWithRoute } from 'angular-routing';
185185
<route path="/">
186186
<app-lazy *routeComponent></app-lazy>
187187
</route>
188-
</router>
189-
`
188+
<route path="/" [exact]="false" redirectTo="/404"> </route>
189+
</router>
190+
`,
190191
})
191-
export class LazyRouteComponent { }
192+
export class LazyRouteComponent {}
192193
```
193194

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

196197
```ts
197198
@NgModule({
198-
declarations: [
199-
LazyRouteComponent,
200-
LazyComponent
201-
]
199+
declarations: [LazyRouteComponent, LazyComponent],
202200
})
203201
export class LazyModule implements ModuleWithRoute {
204202
routeComponent = LazyRouteComponent;
@@ -215,14 +213,13 @@ import { Component } from '@angular/core';
215213
@Component({
216214
template: `
217215
<router>
218-
<route path="/lazy" [load]="components.lazy">
219-
</route>
216+
<route path="/lazy" [load]="components.lazy"> </route>
220217
</router>
221-
`
218+
`,
222219
})
223220
export class MyComponent {
224221
components = {
225-
lazy: () => import('./lazy/lazy.component').then(m => m.LazyComponent)
226-
}
222+
lazy: () => import('./lazy/lazy.component').then((m) => m.LazyComponent),
223+
};
227224
}
228225
```

apps/example-app/src/app/books/books.module.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ import * as fromBooks from '@example-app/books/reducers';
3939
<route path="/">
4040
<bc-collection-page *routeComponent></bc-collection-page>
4141
</route>
42+
<route path="/" [exact]="false" redirectTo="/404"> </route>
4243
</router>
43-
`
44+
`,
4445
})
4546
export class BooksComponent {
4647
loggedIn$ = this.authGuard.canActivate();
@@ -54,15 +55,15 @@ export const COMPONENTS = [
5455
BookPreviewComponent,
5556
BookPreviewListComponent,
5657
BookSearchComponent,
57-
BooksComponent
58+
BooksComponent,
5859
];
5960

6061
export const CONTAINERS = [
6162
FindBookPageComponent,
6263
ViewBookPageComponent,
6364
SelectedBookPageComponent,
6465
CollectionPageComponent,
65-
BooksComponent
66+
BooksComponent,
6667
];
6768

6869
@NgModule({
@@ -90,7 +91,7 @@ export const CONTAINERS = [
9091
EffectsModule.forFeature([BookEffects, CollectionEffects]),
9192
],
9293
declarations: [COMPONENTS, CONTAINERS],
93-
entryComponents: [BooksComponent]
94+
entryComponents: [BooksComponent],
9495
})
9596
export class BooksModule implements ModuleWithRoute {
9697
routeComponent = BooksComponent;

apps/example-app/src/app/core/containers/app.component.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ import { LayoutActions } from '@example-app/core/actions';
3131
>
3232
Browse Books
3333
</bc-nav-item>
34+
<bc-nav-item
35+
(navigate)="closeSidenav()"
36+
*ngIf="loggedIn$ | async"
37+
linkTo="/books/find/bad"
38+
icon="search"
39+
hint="Find your next book!"
40+
>
41+
Browse Books 404
42+
</bc-nav-item>
3443
<bc-nav-item (navigate)="closeSidenav()" *ngIf="!(loggedIn$ | async)">
3544
Sign In
3645
</bc-nav-item>
@@ -43,13 +52,12 @@ import { LayoutActions } from '@example-app/core/actions';
4352
</bc-toolbar>
4453
4554
<router>
46-
<route path="/books/**" [load]="components.books"></route>
55+
<route path="/books" [exact]="false" [load]="components.books"></route>
4756
<route path="/login">
4857
<bc-login-page *routeComponent></bc-login-page>
4958
</route>
50-
<route path="/" redirectTo="/books">
51-
</route>
52-
<route path="**">
59+
<route path="/" redirectTo="/books"> </route>
60+
<route path="/" [exact]="false">
5361
<bc-not-found-page *routeComponent></bc-not-found-page>
5462
</route>
5563
</router>
@@ -58,7 +66,7 @@ import { LayoutActions } from '@example-app/core/actions';
5866
})
5967
export class AppComponent {
6068
components = {
61-
books: () => import('../../books/books.module').then(m => m.BooksModule)
69+
books: () => import('../../books/books.module').then((m) => m.BooksModule),
6270
};
6371
showSidenav$: Observable<boolean>;
6472
loggedIn$: Observable<boolean>;

apps/example-app/src/app/core/containers/not-found-page.component.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Component, ChangeDetectionStrategy } from '@angular/core';
2+
import { Router } from 'angular-routing';
23

34
@Component({
45
selector: 'bc-not-found-page',
@@ -10,7 +11,7 @@ import { Component, ChangeDetectionStrategy } from '@angular/core';
1011
<p>Hey! It looks like this page doesn't exist yet.</p>
1112
</mat-card-content>
1213
<mat-card-actions>
13-
<button mat-raised-button color="primary" linkTo="/">
14+
<button mat-raised-button color="primary" (click)="goHome()">
1415
Take Me Home
1516
</button>
1617
</mat-card-actions>
@@ -24,4 +25,10 @@ import { Component, ChangeDetectionStrategy } from '@angular/core';
2425
`,
2526
],
2627
})
27-
export class NotFoundPageComponent {}
28+
export class NotFoundPageComponent {
29+
constructor(private router: Router) {}
30+
31+
goHome() {
32+
this.router.go('/');
33+
}
34+
}

libs/angular-routing/README.md

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import { RoutingModule } from 'angular-routing';
2626
@NgModule({
2727
imports: [
2828
// ... other imports
29-
RoutingModule.forRoot()
30-
]
29+
RoutingModule.forRoot(),
30+
],
3131
})
3232
export class AppModule {}
3333
```
@@ -40,17 +40,18 @@ import { RoutingModule } from 'angular-routing';
4040
@NgModule({
4141
imports: [
4242
// ... other imports
43-
RoutingModule
44-
]
43+
RoutingModule,
44+
],
4545
})
4646
export class FeatureModule {}
4747
```
4848

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

5151
```html
5252
<router>
53-
<route path="/blog/**">
53+
<!-- For nested routes use exact: false -->
54+
<route path="/blog" [exact]="false">
5455
<app-blog *routeComponent></app-blog>
5556
</route>
5657
<route path="/posts/:postId">
@@ -59,9 +60,8 @@ After your components are registered, use the `Router` and `Route` components to
5960
<route path="/about">
6061
<app-about *routeComponent></app-about>
6162
</route>
62-
<route path="/" redirectTo="/blog">
63-
</route>
64-
<route path="**">
63+
<route path="/" redirectTo="/blog"> </route>
64+
<route path="/" [exact]="false">
6565
<app-page-not-found *routeComponent></app-page-not-found>
6666
</route>
6767
</router>
@@ -84,7 +84,9 @@ To add classes to links that match the current URL path, use the `linkActive` di
8484
```html
8585
<a linkTo="/" linkActive="active">Home</a>
8686
<a linkTo="/about" linkActive="active">About</a>
87-
<a linkTo="/blog" linkActive="active">Blog</a>
87+
<a linkTo="/blog" linkActive="active" [activeOptions]="{ exact: false }"
88+
>Blog</a
89+
>
8890
```
8991

9092
## Using the Router service
@@ -112,7 +114,7 @@ export class MyComponent {
112114

113115
## Using Route Params
114116

115-
To get the route params, inject the `RouteParams` observable. Provide a type for the shape of the route params object.
117+
To get the route params, inject the `RouteParams` observable. Provide a type for the shape of the route params object.
116118

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

133135
## Using Query Params
134136

135-
To get the route params, inject the `QueryParams` observable. Provide a type for the shape of the query params object.
137+
To get the route params, inject the `QueryParams` observable. Provide a type for the shape of the query params object.
136138

137139
```ts
138140
import { Component } from '@angular/core';
@@ -160,15 +162,14 @@ import { Component } from '@angular/core';
160162
@Component({
161163
template: `
162164
<router>
163-
<route path="/lazy/**" [load]="modules.lazy">
164-
</route>
165+
<route path="/lazy" [exact]="false" [load]="modules.lazy"> </route>
165166
</router>
166-
`
167+
`,
167168
})
168169
export class MyComponent {
169170
modules = {
170-
lazy: () => import('./lazy/lazy.module').then(m => m.LazyModule)
171-
}
171+
lazy: () => import('./lazy/lazy.module').then((m) => m.LazyModule),
172+
};
172173
}
173174
```
174175

@@ -184,20 +185,18 @@ import { ModuleWithRoute } from 'angular-routing';
184185
<route path="/">
185186
<app-lazy *routeComponent></app-lazy>
186187
</route>
187-
</router>
188-
`
188+
<route path="/" [exact]="false" redirectTo="/404"> </route>
189+
</router>
190+
`,
189191
})
190-
export class LazyRouteComponent { }
192+
export class LazyRouteComponent {}
191193
```
192194

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

195197
```ts
196198
@NgModule({
197-
declarations: [
198-
LazyRouteComponent,
199-
LazyComponent
200-
]
199+
declarations: [LazyRouteComponent, LazyComponent],
201200
})
202201
export class LazyModule implements ModuleWithRoute {
203202
routeComponent = LazyRouteComponent;
@@ -214,14 +213,13 @@ import { Component } from '@angular/core';
214213
@Component({
215214
template: `
216215
<router>
217-
<route path="/lazy" [load]="components.lazy">
218-
</route>
216+
<route path="/lazy" [load]="components.lazy"> </route>
219217
</router>
220-
`
218+
`,
221219
})
222220
export class MyComponent {
223221
components = {
224-
lazy: () => import('./lazy/lazy.component').then(m => m.LazyComponent)
225-
}
222+
lazy: () => import('./lazy/lazy.component').then((m) => m.LazyComponent),
223+
};
226224
}
227225
```

0 commit comments

Comments
 (0)