Routing with params
Configuring CardItemComponent
Create a new component inside card
which will display the details of the selected item.
ng g c components/card/card-item --skip-tests=true
ActivatedRoute
provides access to information about a route associated with a component that is loaded in an outlet. More here.
this.route.snapshot.paramMap.get('id')
extracts the id
param from the URL which you will pass when you navigate to this component.
history.state
has access to any other extra data you set when you navigate to this component, here it’s data(Card)
.
@Component({
selector: 'app-card-item',
standalone: true,
templateUrl: './card-item.component.html',
styleUrls: ['./card-item.component.scss'],
imports: [
CommonModule,
MatCardModule,
MatButtonModule
]
})
export class CardItemComponent implements OnInit {
id!: string;
data!: Card;
private readonly route = inject(ActivatedRoute);
ngOnInit(): void {
const id = this.route.snapshot.paramMap.get('id');
if (id) {
this.id = id;
}
this.data = history.state?.data;
}
}
<mat-card class="card">
<mat-card-header>
<mat-card-title>{{data.name}}</mat-card-title>
<mat-card-subtitle>{{data.price}}</mat-card-subtitle>
</mat-card-header>
<img mat-card-image [src]="data.imageUrl" alt="card">
<mat-card-content>
<p>{{data.description}}</p>
</mat-card-content>
<mat-card-actions>
<button mat-button color="primary">Update</button>
<button mat-button color="warn">Delete</button>
</mat-card-actions>
</mat-card>
Configuring routes
Add a button in card.component.html
which will navigate to CardItemComponent
.
<div class="card-container">
<mat-card class="card" *ngFor="let card of cards">
...
<mat-card-actions>
<button mat-button color="primary">Details</button>
</mat-card-actions>
</mat-card>
</div>
export class CardComponent {
private readonly router = inject(Router);
private readonly route = inject(ActivatedRoute);
@Input() cards: Card[] = [];
goToItemDetails(data: Card): void {
this.router.navigate(['card-item', data.id], {state: {data}, relativeTo: this.route}).then();
}
}
Router
is a service that provides navigation among views and URL manipulation capabilities.
['card-item', data.id]
is the route url (we will register below), data.id
is dynamic.
{state: {data}, relativeTo: this.route}
, this is the optional configuration
relativeTo: this.route
means routing should be relative to the current url of component. If this was not passed we had to configure our navigation as['card/card-item', data.id]
.state: {data}
is the extra data that we want to pass to navigating component.
The route for the component that displays the details for a specific item would need a route parameter for the ID of that item. We will implement this using the following Routes:
// grocery.routes.ts
export const routes: Routes = [
{ path: '', component: GroceryComponent },
{ path: 'card-item/:id', component: CardItemComponent}
];
For SportsComponent
do the following configuration.
// sports.routes.ts
export const routes: Routes = [
{ path: '', component: SportsComponent },
{ path: 'card-item/:id', component: CardItemComponent }
];
Now on app.route.ts
load those routes as child.
export const routes: Routes = [
{path: '', redirectTo: 'sports', pathMatch: 'full'},
{path: 'sports', loadChildren: () => import('./forms/sports/sports.routes').then(m => m.routes)},
{path: 'grocery', loadChildren: () => import('./forms/grocery/grocery.routes').then(m => m.routes)}
];
in the path of the card-item route places the parameter in the path.