Hello guys how are you? Welcome back on my blog Therichpost. Today in this post I am going to share Building static food ordering application in Angular 19 with Bootstrap 5.
Angular 19 came. If you are new then you must check below two links:
Now guys here is the complete code snippet and please follow carefully:
Here’s a structured plan to build a static food ordering application in Angular 19 with Bootstrap 5. This includes the features you want: a good header and footer, a cart, checkout functionality, and a single item page.
Project Setup
- Create a New Angular Project
ng new food-ordering-app cd food-ordering-app
Choose the routing option and select SCSS as the stylesheet format.
- Install Bootstrap 5
Add Bootstrap to your Angular project:
npm install bootstrap
Update the angular.json file to include Bootstrap styles:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.scss"
]
- Add FontAwesome (Optional)
For icons, install FontAwesome:
npm install @fortawesome/fontawesome-free
Include it in angular.json as well.
Application Structure
- Header Component: Contains navigation links.
- Footer Component: Displays footer content.
- Home Component: Displays a list of food items.
- Single Item Page: Detailed view of a food item.
- Cart Component: Displays items in the cart.
- Checkout Component: Form to input customer details and finalize the order.
Components and Routing
Generate the necessary components:
ng generate component components/header ng generate component components/footer ng generate component pages/home ng generate component pages/single-item ng generate component pages/cart ng generate component pages/checkout
Configure routes in app-routs.ts:
import { Routes } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { SingleItemComponent } from './pages/single-item/single-item.component';
import { CartComponent } from './pages/cart/cart.component';
import { CheckoutComponent } from './pages/checkout/checkout.component';
export const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'item/:id', component: SingleItemComponent },
{ path: 'cart', component: CartComponent },
{ path: 'checkout', component: CheckoutComponent },
];
Component Details
Header Component
Include navigation links and a cart icon:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" routerLink="/">Food Ordering</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link" routerLink="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="/cart">Cart</a>
</li>
</ul>
</div>
</div>
</nav>
Footer Component
Create a sticky footer with copyright info:
<footer class="bg-dark text-white text-center py-3"> © 2025 Food Ordering App. All rights reserved. </footer>
Home Component
Display a grid of food items:
<div class="container mt-4">
<div class="row">
<div class="col-md-4" *ngFor="let item of foodItems">
<div class="card">
<img src="{{ item.image }}" class="card-img-top img-fluid" style="height: 250px; object-fit: cover;" alt="{{ item.name }}">
<div class="card-body">
<h5 class="card-title">{{ item.name }}</h5>
<p class="card-text">{{ item.description }}</p>
<p class="card-text text-primary">${{ item.price }}</p>
<a [routerLink]="['/item', item.id]" class="btn btn-primary">View Details</a>
</div>
</div>
</div>
</div>
</div>
<div class="container mt-5 mb-5">
<h2>Special Offers</h2>
<div class="row">
<div class="col-md-4">
<div class="card bg-warning text-white">
<img src="assets/images/pasta.jpg" class="card-img-top" style="height: 250px; object-fit: cover;" alt="Special Offer">
<div class="card-body">
<h5 class="card-title">Buy 1 Get 1 Free Pizza</h5>
<p class="card-text">Order any large pizza and get another one for free! Limited time only.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card bg-danger text-white">
<img src="assets/images/pizza.jpg" class="card-img-top" style="height: 250px; object-fit: cover;" alt="Special Offer">
<div class="card-body">
<h5 class="card-title">10% Off on Your First Order</h5>
<p class="card-text">Enjoy 10% off your first order with us. Use code FIRST10.</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card bg-success text-white">
<img src="assets/images/burger.jpg" class="card-img-top" style="height: 250px; object-fit: cover;" alt="Special Offer">
<div class="card-body">
<h5 class="card-title">Free Drink with Every Burger</h5>
<p class="card-text">Get a free soft drink with every burger ordered. Don't miss out!</p>
</div>
</div>
</div>
</div>
</div>
<div class="container mt-5 py-5 newsletter-section bg-light rounded-3 shadow">
<div class="row align-items-center">
<!-- Left Content: Text and Details -->
<div class="col-md-6 text-center text-md-start">
<h2 class="fw-bold">Stay Updated!</h2>
<p class="text-muted">Subscribe to our newsletter and get exclusive offers, updates, and mouth-watering recipes delivered straight to your inbox.</p>
</div>
<!-- Right Content: Subscription Form -->
<div class="col-md-6">
<form class="d-flex">
<input type="email" class="form-control me-2 rounded-pill shadow-sm" placeholder="Enter your email" aria-label="Enter your email" required>
<button class="btn btn-primary px-4 rounded-pill shadow-sm" type="submit">Subscribe</button>
</form>
<!-- Optional Privacy Text -->
<small class="d-block mt-2 text-muted">We respect your privacy. Unsubscribe anytime.</small>
</div>
</div>
</div>
Single Item Component
Show detailed info and add to cart:
<div class="container mt-4">
<h2>{{ item.name }}</h2>
<img [src]="item.image" class="card-img-top img-fluid" style="height: 350px; object-fit: cover;" alt="{{ item.name }}">
<p>{{ item.description }}</p>
<p class="text-primary">Price: ${{ item.price }}</p>
<button class="btn btn-success" (click)="addToCart()">Add to Cart</button>
</div>
Cart Component
Display selected items:
<div class="container mt-4">
<h2>Your Cart</h2>
<div *ngIf="cartItems.length === 0">Your cart is empty!</div>
<table class="table" *ngIf="cartItems.length > 0">
<thead>
<tr>
<th>Item</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of cartItems">
<td>{{ item.name }}</td>
<td>${{ item.price }}</td>
<td>{{ item.quantity }}</td>
<td>${{ item.price * item.quantity }}</td>
</tr>
</tbody>
</table>
<a routerLink="/checkout" class="btn btn-primary">Proceed to Checkout</a>
</div>
Checkout Component
Form for user details:
<div class="container mt-4">
<h2>Checkout</h2>
<form (ngSubmit)="placeOrder()">
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" id="name" class="form-control" required>
</div>
<div class="mb-3">
<label for="address" class="form-label">Address</label>
<input type="text" id="address" class="form-control" required>
</div>
<div class="mb-3">
<label for="card" class="form-label">Card Number</label>
<input type="text" id="card" class="form-control" required>
</div>
<button type="submit" class="btn btn-success">Place Order</button>
</form>
</div>
Styling
Add global styles in src/styles.scss for consistency:
/* You can add global styles to this file, and also import other style files */
body {
font-family: 'Arial', sans-serif;
}
footer {
width: 100%;
}
/* Add to styles.scss */
.navbar {
position: fixed;
width: 100%;
top: 0;
z-index: 1000;
}
body {
padding-top: 56px; /* Adjust this value to match navbar height */
}
.newsletter-section {
background: linear-gradient(135deg, #f8f9fa, #e9ecef); /* Subtle gradient background */
padding: 2rem 1rem;
}
.newsletter-section h2 {
color: #343a40; /* Darker text for contrast */
}
.newsletter-section .form-control {
border: 2px solid #dee2e6; /* Slight border for better visibility */
transition: all 0.3s ease; /* Smooth interaction effect */
}
.newsletter-section .form-control:focus {
border-color: #0d6efd; /* Highlight on focus */
box-shadow: 0 0 10px rgba(13, 110, 253, 0.5); /* Glowing effect */
}
.newsletter-section .btn-primary {
background: #0d6efd; /* Bootstrap primary color */
border: none;
transition: all 0.3s ease; /* Smooth hover effect */
}
.newsletter-section .btn-primary:hover {
background: #084298; /* Darker blue on hover */
}
.newsletter-section small {
font-size: 0.85rem;
}
Mock Data
Populate it with sample data and methods for managing the cart.
Create a service to handle food items and cart operations:
Generate the Service
ng generate service services/food
Service Implementation (food.service.ts)
import { Injectable } from '@angular/core';
interface FoodItem {
id: number;
name: string;
description: string;
price: number;
image: string;
quantity?: number; // Optional for cart purposes
}
@Injectable({
providedIn: 'root',
})
export class FoodService {
private foodItems: FoodItem[] = [
{ id: 1, name: 'Pizza', description: 'Cheesy delight', price: 10, image: 'assets/images/pizza.jpg' },
{ id: 2, name: 'Burger', description: 'Juicy and tasty', price: 8, image: 'assets/images/burger.jpg' },
{ id: 3, name: 'Pasta', description: 'Italian classic', price: 12, image: 'assets/images/pasta.jpg' },
];
private cart: FoodItem[] = [];
getFoodItems(): FoodItem[] {
return this.foodItems;
}
getFoodItemById(id: number): FoodItem | undefined {
return this.foodItems.find(item => item.id === id);
}
getCartItems(): FoodItem[] {
return this.cart;
}
addToCart(item: FoodItem): void {
const cartItem = this.cart.find(cartItem => cartItem.id === item.id);
if (cartItem) {
cartItem.quantity! += 1;
} else {
this.cart.push({ ...item, quantity: 1 });
}
}
clearCart(): void {
this.cart = [];
}
}
Food Item Display
Home Component (home.component.ts)
import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { CommonModule } from '@angular/common';
import { FoodService } from '../../services/food.service';
@Component({
selector: 'app-home',
standalone: true,
imports: [RouterLink, CommonModule],
templateUrl: './home.component.html',
styleUrl: './home.component.css'
})
export class HomeComponent {
foodItems:any;
constructor(private foodService: FoodService) {}
ngOnInit(): void {
this.foodItems = this.foodService.getFoodItems();
}
}
Single Item Page
Component (single-item.component.ts)
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { FoodService } from '../../services/food.service';
@Component({
selector: 'app-single-item',
templateUrl: './single-item.component.html',
styleUrls: ['./single-item.component.scss'],
})
export class SingleItemComponent implements OnInit {
item: any;
constructor(
private route: ActivatedRoute,
private foodService: FoodService
) {}
ngOnInit(): void {
const itemId = Number(this.route.snapshot.paramMap.get('id'));
this.item = this.foodService.getFoodItemById(itemId);
}
addToCart(): void {
this.foodService.addToCart(this.item);
alert(`${this.item.name} added to cart!`);
}
}
Cart Page
Component (cart.component.ts)
import { Component } from '@angular/core';
import { FoodService } from '../../services/food.service';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-cart',
standalone: true,
imports: [CommonModule, RouterLink],
templateUrl: './cart.component.html',
styleUrl: './cart.component.css'
})
export class CartComponent {
cartItems:any;
constructor(private foodService: FoodService) {}
ngOnInit(): void {
this.cartItems = this.foodService.getCartItems();
}
}
Checkout Page
Component (checkout.component.ts)
import { Component } from '@angular/core';
import { FoodService } from '../../services/food.service';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
@Component({
selector: 'app-checkout',
standalone: true,
imports: [],
templateUrl: './checkout.component.html',
styleUrl: './checkout.component.css'
})
export class CheckoutComponent {
constructor(private foodService: FoodService) {}
placeOrder(): void {
alert('Order placed successfully!');
this.foodService.clearCart();
}
}
This should now be a complete static food ordering app with Angular 19 and Bootstrap 5. If you’d like further refinements or additions, let me know and feel free to comment below!
Ajay
Thanks
