This is my products dashboard.html
<nav #nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
<button class="nav-link active" id="nav-categories-tab" data-bs-toggle="tab" data-bs-target="#nav-categories" type="button" role="tab" aria-controls="nav-categories" aria-selected="true" (click)="showCategories()" [ngClass]="{ 'active':activeTab==='categories'}">Categories</button>
<button class="nav-link" id="nav-product-lists-tab" data-bs-toggle="tab" data-bs-target="#nav-product-lists" type="button" role="tab" aria-controls="nav-product-lists" aria-selected="false"(click)="showProducts()" [ngClass]="{ 'active':activeTab==='products'}">Products</button>
<button class="nav-link" id="nav-product-details-tab" data-bs-toggle="tab" data-bs-target="#nav-product-details" type="button" role="tab" aria-controls="nav-product-details" aria-selected="false" (click)="showProductDetails()" [ngClass]="{ 'active':activeTab==='product-details'}">Product Details</button>
</div>
</nav>
This is my products dashboard component
export class ProductsDashboardComponent {
activeTab = 'categories';
constructor(private router:Router, private route: ActivatedRoute){}
showCategories(){
this.router.navigate(['categories'],{relativeTo: this.route})
}
showProducts(){
this.router.navigate(['products'],{relativeTo: this.route})
}
showProductDetails(){
this.activeTab = 'product-details';
this.router.navigate(['product-details'],{relativeTo: this.route})
}
}
Now when I click product details tab the previous tab which is products tab also shown as active as shown below. So, how do I make the other tabs class inactive.
products.html
<div class="container">
<div class="list row ms-3">
<div class="col-md-12">
@if(hidden){
<p-table [value]="products" styleClass="p-datatable-striped">
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>Image</th>
<th>Category</th>
<th>Price</th>
<th>Actions</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-product>
<tr>
<td>{{product.title}}</td>
<td><img [src]="product.image" [alt]="product.title" width="100" class="shadow-4" /></td>
<td>{{product.category}}</td>
<td>{{product.price | currency:'USD'}}</td>
<td><a class="btn btn-outline-primary" (click)="getProductDetailsById(product,'product-details')">View</a></td>
<td><a class="btn btn-info" (click)="getProductById(product)">Edit</a></td>
<td><button class="btn btn-danger" (click)="deleteProduct(product)"> Delete</button></td>
</tr>
</ng-template>
<ng-template pTemplate="summary">
<div class="flex align-items-center justify-content-between">
In total there are {{products ? products.length : 0 }} products.
</div>
</ng-template>
</p-table>
</div>
</div>
</div>
products component
getProductDetailsById(product: Products,name:string){
this.productService.get(product.id)
.subscribe( data => {
this.currentProduct=data;
this.currentIndex = data["id"],
this.parent.activeTab = name;
this.router.navigate(['products-dashboard/product-details/',this.currentIndex])
})
}
Now If I click view button then it should navigate to product-details tab
product-details.html
<div class="container">
<div class="row ms-3">
<div class="card" style="width: 18rem;">
<img src={{currentProduct.image}} class="card-img-top" alt={{currentProduct.title}}>
<div class="card-body">
<h5 class="card-title">{{currentProduct.title}}</h5>
<h3 class="card-title">{{currentProduct.price | currency:'USD'}}</h3>
<p class="card-text">{{currentProduct.description}}</p>
</div>
</div>
</div>
</div>
product-details component
import { Component, Inject, Input, OnInit, ViewChild } from '@angular/core';
import {ActivatedRoute, NavigationEnd, Router, RouterLink } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { Products } from '../models/products.model';
import {ProductService } from '../services/products.service';
import { ProductsDashboardComponent } from '../products-dashboard/products-dashboard.component';
import { filter } from 'rxjs';
@Component({
selector: 'app-product-details',
standalone: true,
imports: [FormsModule, CommonModule,ReactiveFormsModule, RouterLink],
providers:[ProductService],
templateUrl: './product-details.component.html',
styleUrl: './product-details.component.css'
})
export class ProductDetailsComponent implements OnInit{
@Input() currentProduct: Products = {
title: '',
image: '',
category:'',
price: ''
};
nav:any;
message = '';
activeTab = 'categories';
constructor(
private router:Router, private route: ActivatedRoute,
private productService: ProductService,
@Inject(ProductsDashboardComponent) private parent: ProductsDashboardComponent) {}
ngOnInit(): void {
this.message = '';
this.router.events.pipe(
filter(event => event instanceof NavigationEnd)
).subscribe(() => {
this.parent.activeTab = this.route?.snapshot?.firstChild?.routeConfig?.path || '';
})
this.getProduct(this.route.snapshot.params["id"]);
}
getProduct(id: string): void {
this.productService.get(id)
.subscribe({
next: (data) => {
this.currentProduct = data;
console.log(data);
this.currentProduct.id = data["id"]
this.currentProduct.title = data["title"]
this.currentProduct.category = data["category"]
this.currentProduct.image = data["image"]
this.currentProduct.price = data["price"]
this.currentProduct.description = data["description"]
},
error: (e) => console.error(e)
});
}
}
Now the product shows in the same tab itself
app.routes.ts
export const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' }, // redirect to `first-component`
{ path: 'home', component: HomeComponent},
{ path: 'hooks', component: HooksComponent},
{ path: 'dashboard', component: DashboardComponent},
{ path: 'products-dashboard', component: ProductsDashboardComponent,
children:[
{path: 'categories', component: CategoriesComponent},
{path: 'products', component: ProductsComponent},
{path: 'product-details', component: ProductDetailsComponent},
{path: "product-details/:id", component: ProductDetailsComponent },
]
},
{ path: '**', component: PagenotfoundComponent }, // Wildcard route for a 404 page
];



Below are the changes I made.
productsand need to go toproduct-detailsso we go one step back../toproduct-dashboardand then we navigate toproduct-detailscode
Second, we need to listen for the tab selection only on the parent
product-dashboardwe can remove the code fromproduct-detailsI have added router params subscription, since it will dynamic and will show the proper value even when the component is not destroyed!
code
ngOnDestroythis will prevent memory leaks in your application!I hope this solves your issue!
products html
products ts
product details html
product details ts
product dashboard html
product dashboard ts
stackblitz