Skip to content

Commit 6410ab4

Browse files
authored
docs: convert component sidenav guard to a functional guard (#33877)
Replaces the class-based `CanActivateComponentSidenav` guard with a functional `CanActivateFn`. Instead of triggering a separate navigation and returning `false`, the guard now returns a `UrlTree` so the router handles the redirect as part of the current navigation.
1 parent 4448bb7 commit 6410ab4

3 files changed

Lines changed: 45 additions & 19 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {TestBed} from '@angular/core/testing';
2+
import {ActivatedRouteSnapshot, provideRouter, Router, UrlSegment, UrlTree} from '@angular/router';
3+
import {canActivateComponentSidenav} from './component-sidenav-can-load-guard';
4+
5+
describe('canActivateComponentSidenav', () => {
6+
beforeEach(() => {
7+
TestBed.configureTestingModule({
8+
providers: [provideRouter([])],
9+
});
10+
});
11+
12+
function runGuard(section: string) {
13+
const route = {url: [new UrlSegment(section, {})]} as unknown as ActivatedRouteSnapshot;
14+
return TestBed.runInInjectionContext(() => canActivateComponentSidenav(route, {} as any));
15+
}
16+
17+
it('should allow activation for a known section', () => {
18+
expect(runGuard('components')).toBe(true);
19+
expect(runGuard('cdk')).toBe(true);
20+
});
21+
22+
it('should match the section case-insensitively', () => {
23+
expect(runGuard('CDK')).toBe(true);
24+
});
25+
26+
it('should redirect to the root for an unknown section', () => {
27+
const result = runGuard('unknown');
28+
const router = TestBed.inject(Router);
29+
30+
expect(result instanceof UrlTree).toBe(true);
31+
expect(router.serializeUrl(result as UrlTree)).toBe('/');
32+
});
33+
});

‎docs/src/app/pages/component-sidenav/component-sidenav-can-load-guard.ts‎

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,20 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Service, inject} from '@angular/core';
10-
import {ActivatedRouteSnapshot, Router} from '@angular/router';
9+
import {inject} from '@angular/core';
10+
import {CanActivateFn, Router} from '@angular/router';
1111
import {SECTIONS} from '../../shared/documentation-items/documentation-items';
1212

1313
/**
1414
* Guard to determine if the sidenav can load, based on whether the section exists in documentation
1515
* items.
1616
*/
17-
@Service()
18-
export class CanActivateComponentSidenav {
19-
private _router = inject(Router);
20-
21-
canActivate(route: ActivatedRouteSnapshot) {
22-
// Searches if the section defined in the base UrlSegment is a valid section from the
23-
// documentation items. If found, returns true to allow activation, otherwise blocks activation
24-
// and navigates to '/'.
25-
if (Object.keys(SECTIONS).some(s => s.toLowerCase() === route.url[0].path.toLowerCase())) {
26-
return true;
27-
}
28-
29-
this._router.navigateByUrl('/');
30-
return false;
17+
export const canActivateComponentSidenav: CanActivateFn = route => {
18+
// Searches if the section defined in the base UrlSegment is a valid section from the
19+
// documentation items. If found, returns true to allow activation, otherwise redirects to '/'.
20+
if (Object.keys(SECTIONS).some(s => s.toLowerCase() === route.url[0].path.toLowerCase())) {
21+
return true;
3122
}
32-
}
23+
24+
return inject(Router).parseUrl('/');
25+
};

‎docs/src/app/routes.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import {Component} from '@angular/core';
1010
import {Route, Routes} from '@angular/router';
11-
import {CanActivateComponentSidenav} from './pages/component-sidenav/component-sidenav-can-load-guard';
11+
import {canActivateComponentSidenav} from './pages/component-sidenav/component-sidenav-can-load-guard';
1212

1313
@Component({template: ''})
1414
export class RedirectPlaceholder {}
@@ -73,7 +73,7 @@ export const MATERIAL_DOCS_ROUTES: Routes = [
7373
},
7474
{
7575
path: ':section',
76-
canActivate: [CanActivateComponentSidenav],
76+
canActivate: [canActivateComponentSidenav],
7777
loadChildren: () =>
7878
import('./pages/component-sidenav/component-sidenav').then(m => m.componentSidenavRoutes),
7979
},

0 commit comments

Comments
 (0)