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