In this guide, I'll walk you through creating a responsive Angular-based e-commerce product list that utilizes Object Data Structures. We'll make use of services to manage product data and display it dynamically in a grid layout. We'll also employ Flexbox and CSS Grid for layout and follow the BEM CSS architecture for styling.
Product Model
We need to create a model for our products. This will define the structure of the product objects, which will be used throughout the application.
Create a file product.model.ts
:
export interface Product {
id: number;
name: string;
description: string;
price: string;
imageUrl: string;
}
This model ensures we have a structured format for each product.
Creating the Product Service
Next, we need a service to manage the product data. We’ll add a list of products with placeholder image URLs.
Create the service product.service.ts
:
import { Injectable } from '@angular/core';
import { Product } from './product.model';
@Injectable({
providedIn: 'root',
})
export class ProductService {
getProducts(): Product[] {
return [
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
{
id: 1,
name: 'Bluetooth Speaker',
description: 'Portable with excellent sound.',
price: '1000',
imageUrl: 'image/speaker.jpg',
},
];
}
}
This component fetches the list of products from the service and stores them in the products
array.
Displaying the Products in the Component
Now, we need to fetch and display the product data in the component. We'll be using Flexbox and CSS Grid for the layout.
Create the component product.component.ts
:
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProductService } from './product.service';
@Component({
selector: 'app-product',
standalone: true,
templateUrl: './product.component.html',
styleUrls: ['./product.component.css'],
imports: [CommonModule],
providers: [ProductService],
})
export class ProductComponent implements OnInit {
products: any[] = [];
constructor(private productService: ProductService) {}
ngOnInit(): void {
this.products = this.productService.getProducts();
}
}
Designing the Layout with Grid and Flex
We’ll be using CSS Grid for the overall layout and Flexbox within the individual product cards to align elements.
Create the layout in product.component.html
:
<main class="product-container">
<div class="product-card" *ngFor="let product of products">
<img class="product-card__image" [src]="product.imageUrl" [alt]="product.name" />
<h3 class="product-card__title">{{ product.name }}</h3>
<p class="product-card__description">{{ product.description }}</p>
<p class="product-card__price">₱{{ product.price }}</p>
<button class="product-card__button--primary" (click)="addToCart(product)">Add to Cart</button>
<button class="product-card__button--secondary" (click)="addToWishlist(product)">Wishlist</button>
</div>
</main>
This HTML uses *ngFor
to loop over the products and display them in individual cards.
BEM CSS Architecture for Styling
Now, let’s apply BEM CSS architecture to our styles for maintainability and clarity.
Create the CSS for the layout in product.component.css
:
.product-grid {
display: grid;
gap: 20px;
grid-template-columns: repeat(2, 1fr); /* Mobile */
padding: 20px;
}
@media (min-width: 768px) {
.product-grid {
grid-template-columns: repeat(3, 1fr); /* Tablet */
}
}
@media (min-width: 1024px) {
.product-grid {
grid-template-columns: repeat(5, 1fr); /* Desktop */
}
}
.product-card {
background-color: #fff;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
overflow: hidden;
text-align: center;
display: flex;
flex-direction: column;
padding: 15px;
transition: transform 0.3s ease;
}
.product-card:hover {
transform: translateY(-5px);
}
.product-card__image {
width: 100%;
height: 180px;
object-fit: cover;
border-radius: 4px;
}
.product-card__badges {
margin: 10px 0;
}
.badge {
display: inline-block;
padding: 4px 8px;
border-radius: 12px;
font-size: 0.8rem;
font-weight: bold;
margin-right: 5px;
}
.badge--primary {
background-color: #007bff;
color: #fff;
}
.badge--secondary {
background-color: #6c757d;
color: #fff;
}
.product-card__title {
font-size: 1.2rem;
margin: 10px 0 5px;
color: #333;
}
.product-card__description {
font-size: 0.9rem;
color: #666;
margin-bottom: 15px;
}
.product-card__buttons {
margin-top: auto;
}
.button {
padding: 8px 15px;
border: none;
border-radius: 4px;
font-size: 0.9rem;
cursor: pointer;
margin: 5px;
transition: background-color 0.3s ease;
}
.button--primary {
background-color: #007bff;
color: #fff;
}
.button--primary:hover {
background-color: #0056b3;
}
.button--secondary {
background-color: #6c757d;
color: #fff;
}
.button--secondary:hover {
background-color: #5a6268;
}
The
.product-container
uses CSS Grid for the overall layout with responsive columns based on the screen size.Each product card uses Flexbox to align items vertically.
2 columns for mobile, 3 columns for tablets, and 5 columns for desktops.
GitHub Link: https://github.com/RodelDecio/Angular-Ecommerce-Product-List.git
Hosting URL: https://angularecommerceproductl-35506.web.app