Dynamic Routing with API - Product Details Page

A product listing page and a product detail page are created.

When a product is clicked, it opens a new page with full details.


What is Being Built

A product list page shows product names as links.

On clicking any product, a detail page opens.

The detail page shows image, title, price, category, description, rating, and stock.

This is similar to e-commerce websites.


Components Created

Two components are created:

  1. Product list component
  2. Product detail component

Command used:


ng g c components/product-list
ng g c components/product-details


Routing Setup

Routes are defined in app.routes.ts.

{
path: '',
component: ProductListComponent
},
{
path: 'details/:id',
component: ProductDetailsComponent
}

Empty path shows product listing.

details/:id is used for dynamic routing.


Router Outlet Setup

RouterOutlet is imported in app.ts.


imports: [RouterOutlet]

HTML uses:


<router-outlet></router-outlet>


Moving Product List Code

API call and product list logic are moved from app.ts

They are placed inside product-list.component.ts.

Signals and service are imported properly.


Showing Product List as Links

Only product title is shown as a link.

<a routerLink="details/{{product.id}}">
{{ product.title }}
</a>

RouterLink is imported in the component.


Dynamic ID in Route

Route is changed to dynamic using :id.

path: 'details/:id'

Product ID is passed in the URL.


Getting ID in Product Details Component

ActivatedRoute is used to read route parameter.

constructor(private route: ActivatedRoute) {}

ngOnInit() {
const productId = this.route.snapshot.params['id'];
}

ID is received correctly when clicking different products.


Fetching Product Details Using ID

Same API is used to get all products.

Selected product is filtered using ID.

this.products.getProducts().subscribe((data)=>{
console.log(data.products);
data.products.filter((item)=>{
if(item.id.toString()==productId){
this.productData.set(item)
}

Filtered product is the clicked one.


Storing Selected Product in Signal

Only one product is stored.

productData = signal<Product | undefined>(undefined);

this.productData.set(item[0]);


Displaying Product Details in HTML

<img [src]="productData()?.thumbnail" />

<h2>{{ productData()?.title }}</h2>
<p>Description: {{ productData()?.description }}</p>
<p>Price: {{ productData()?.price }}</p>
<p>Rating: {{ productData()?.rating }}</p>
<p>Stock: {{ productData()?.stock }}</p>

Optional chaining is used because data can be undefined.