🛍️ Step 6: Product Module – Low Level Design (LLD)
This document describes the low-level implementation details of the products feature module in the Angular e-commerce frontend.
📦 Module Structure
src/
├── app/
│ └── features/
│ └── products/
│ ├── components/
│ │ ├── product-list/
│ │ │ ├── product-list.component.ts
│ │ │ └── product-list.component.html
│ │ ├── product-card/
│ │ │ ├── product-card.component.ts
│ │ │ └── product-card.component.html
│ │ └── product-detail/
│ │ ├── product-detail.component.ts
│ │ └── product-detail.component.html
│ ├── services/
│ │ └── product.service.ts
│ ├── store/
│ │ ├── product.actions.ts
│ │ ├── product.reducer.ts
│ │ ├── product.effects.ts
│ │ └── product.selectors.ts
│ ├── models/
│ │ └── product.model.ts
│ ├── products-routing.module.ts
│ └── products.module.ts
🧱 Component Breakdown
📋 ProductListComponent
- Displays list of products with filters and pagination
- Dispatches
LoadProducts()and listens toproductsstore slice - Utilizes
ProductCardComponentfor each product
🃏 ProductCardComponent
- Shows product image, title, price, rating
- Emits
selectoraddToCartevents
🔍 ProductDetailComponent
- Displays detailed product info: images, description, specs, reviews
- Dispatches
LoadProductById({ id }) - Integrates with cart and wishlist actions
🧪 Service: ProductService
Handles API interaction for product-related operations.
@Injectable({ providedIn: "root" })
export class ProductService {
constructor(private http: HttpClient) {}
getProducts(filters?: Filters): Observable<Product[]> {
return this.http.get<Product[]>("/api/products", { params: filters });
}
getProductById(id: string): Observable<Product> {
return this.http.get<Product>(`/api/products/${id}`);
}
}
🧩 NgRx Store (optional)
✅ Actions – product.actions.ts
export const loadProducts = createAction(
"[Product] Load Products",
props<{ filters?: Filters }>()
);
export const loadProductsSuccess = createAction(
"[Product] Load Products Success",
props<{ products: Product[] }>()
);
export const loadProductsFailure = createAction(
"[Product] Load Products Failure",
props<{ error: any }>()
);
export const loadProduct = createAction(
"[Product] Load Product",
props<{ id: string }>()
);
export const loadProductSuccess = createAction(
"[Product] Load Product Success",
props<{ product: Product }>()
);
🔁 Reducer – product.reducer.ts
- Maintains
products,selectedProduct, loading, and error state
🌐 Effects – product.effects.ts
- Calls
getProducts()orgetProductById()APIs - Dispatches success/failure actions
🔍 Selectors – product.selectors.ts
export const selectAllProducts = createSelector(
selectProductState,
(state) => state.products
);
export const selectSelectedProduct = createSelector(
selectProductState,
(state) => state.selectedProduct
);
🔄 API Contracts
| Endpoint | Method | Request Body | Response |
|---|---|---|---|
/api/products |
GET | filters? |
Product[] |
/api/products/:id |
GET | – | Product |
📐 Models
export interface Product {
id: string;
name: string;
description: string;
images: string[];
price: number;
currency: string;
category?: string;
rating?: number;
stock?: number;
}
export interface Filters {
category?: string;
priceMin?: number;
priceMax?: number;
search?: string;
}
🚦 Routing
const routes: Routes = [
{ path: "products", component: ProductListComponent },
{ path: "products/:id", component: ProductDetailComponent },
];
✅ Responsibilities Summary
| Part | Responsibility |
|---|---|
ProductListComponent |
Fetch and display list of products |
ProductCardComponent |
Render individual product details and actions |
ProductDetailComponent |
Show full product info and integrate cart/wishlist |
ProductService |
API integration for product retrieval |
Store (NgRx) |
Maintain products state, selected product data |