#
Angular
#
Create a project with a specific Angular version
npx -p @angular/cli@16.2.14 ng new {projectName}
#
Pass component inputs in route
Receive the route data, path parameters, query parameters for a route as component input.
const routes = [
path: 'about',
loadComponent: import('./about'),
resolve: { contact: () => getContact() }
];
@Component(...)
export class About {
@Input() contact?: string;
}
#
Marking inputs as required
@Input({ required: true }) title: string = '';
#
ngTemplate, ngTemplateOutlet and ngTemplateOutletContext
Example
<ng-container *ngFor="let l of currentLetters"
[ngTemplateOutlet]="letterKey"
[ngTemplateOutletContext]="{ letter: l }">
</ng-container>
<ng-template #letterKey let-letter="letter">
<div class="letter-key" (click)="onLetterClick(letter)"></div>
</ng-template>
#
Navigate to relative, preserve any query params
Example
this.router.navigate(['edit'], {relativeTo: this.route, queryParamsHandling: 'preserve'});
Note: Can also use 'merge' if adding new ones.
#
Passing query parameters and fragments
E.g. to change URL to /servers/5/edit?allowEdit=1#loading
Using HTML
<a
[routerLink]="['/servers', 5, 'edit']"
[queryParams]="{allowEdit: '1'}
fragment="loading">
Link name
</a>
Using JS
import { Router } from '@angular/router';
constructor(private router: Router) { }
fnName(id: number) {
this.router.navigate(['/servers', id, 'edit'], {queryParams: allowEdit: '1'}, fragment: 'loading');
}
#
Retrieve params, query parameters and fragments
import { ActivatedRoute } from '@angular/router';
constructor(private route: ActivatedRoute) { }
// not reactive, will not change after component is loaded
const params = this.route.snapshot.params['id'];
const query = this.route.snapshot.queryParams;
const fragment = this.route.snapshot.fragment;
// subscribe to changes, no need to destroy
this.route.params.subscribe(
params: Params) => {
query = +params['id'];
}
);
this.route.queryParams.subscribe();
this.route.fragment.subscribe();
Note: params is always string. Convert by adding +params['id']
#
Setting up nested routes
Example
const appRoutes: Routes = [
{ path: 'servers', component: ServersComponent, children: [
{ path: ':id', component: ServerComponent },
{ path: ':id/edit', component: EditServerComponent }
]}
]
<router-outlet></router-outlet>
#
Auth guard for protecting paths
Use either canActivate
to protect whole path, or canActivateChild
to protect only the child paths.
Route
const appRoutes: Routes = [
{ path: 'servers',
component: ServersComponent,
canActivate: [AuthGuard],
canActivateChild: [AuthGuard],
children: [
{ path: ':id', component: ServerComponent },
{ path: ':id/edit', component: EditServerComponent }
]}
]
AuthGuard
canActivate(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.authService.isAuthenticated()
.then(
(authenticated: boolean) => {
if (authenticated) {
return true;
} else {
this.router.navigate(['/']);
}
}
);
}
canActivateChild(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.canActivate(route, state);
}
#
Get static data from router
Route
const appRoutes: Routes = [
{ path: 'servers',
component: ServersComponent,
data: {
msg: 'Hello'
}
}
]
constructor(private route: ActivatedRoute) { }
this.route.data.subscribe(
(data: Data) => {
const test = data['msg'];
}
);
#
Lazy load routes
Search "Angular standalone routing".
export const routes = [
{
path: 'items',
loadChildren: () => import('./items/items.routes');
}
]
#
Lazy load components
export const routes = [
{
path: 'items',
loadComponent: () => import('./items/items.component');
}
]