Build a Shopping Cart in Angular

Sunil Joshi
The Startup
Published in
7 min readSep 9, 2020

In this article, we are going to build a shopping cart front-end with Angular for our application.

You can check our backend part built in Nodejs, which we already have published.

Note that you need to have the angular CLI installed on your local machine. To upgrade to Angular you can follow up on this tutorial.

To start up we need to set up our application directory. Create an angular-cart directory on your desktop and run this command to set up a new angular project:

cd desktop
mkdir angular-cart && cd angular-cart
ng new angular-cart

Running the ng new the command will prompt some questions for the project scaffolding. Type y to add Angular routing to that project and select css as the default stylesheet.

Selecting these two things will create a new Angular project. You can move into the project directory and then use the code . command to open up our project in VS Code.

To serve our application we can run ng serve which will open up our application on port 4200.

We will continue by setting up our user interface for the application. You can get all our UI components from WrapPixel’s UI Kit.

WrapPixel for Best Angular Resources

WrapPixel is an online template store where you could get great Angular Dashboard Template and Angular Material Themes.

We will create our components for a listing of products and cart details. We will also define a navbar component for page navigation.

To create a component run this on your terminal:

ng g c components/cart
ng g c components/navbar
ng g c components/products

This will create a components directory and create a cart module where we will define our markup and styles.

We need to configure Bootstrap into our application by adding the CDN to the src/dex.html file.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AngularCart</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>

Sponsored:

Define the Navbar

Let’s define our navbar by editing the codes in the components/navbar/navbar.components.html to this:

<nav class="navbar navbar-expand-lg navbar-light bg-info">
<div class="container">
<a routerLink="/" class="navbar-brand">Angular Cart</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a routerLink="/" class="nav-link">Home </a>
</li>
<li class="nav-item">
<a routerLink="/cart" class="nav-link">Cart </a>
</li>
</ul>
</div>
</div>
</nav>

And then modify the codes in the app/app.components.html to this:

<app-navbar></app-navbar>
<section>
<div class="banner-innerpage" style="
background-image: url(https://images.pexels.com/photos/1005638/pexels-photo-1005638.jpeg?cs=srgb&dl=pexels-oleg-magni-1005638.jpg&fm=jpg);
">
<div class="container">
<!-- Row -->
<div class="row justify-content-center">
<!-- Column -->
<div class="col-md-6 align-self-center text-center" data-aos="fade-down" data-aos-duration="1200">
<h1 class="title">Shop listing</h1>
<h6 class="subtitle op-8">
We are small team of creative people working together.
</h6>
</div>
<!-- Column -->
</div>
</div>
</div>
</section>
<router-outlet></router-outlet>

We will add some styles in the app.component.css :

.banner-innerpage {
padding: 150px 0 100px;
background-size: cover;
background-position: center center;
}
.banner-innerpage .title {
color: #ffffff;
text-transform: uppercase;
font-weight: 700;
font-size: 40px;
line-height: 40px;
}
.banner-innerpage .subtitle {
color: #ffffff;
}
.shop-listing .shop-hover {
position: relative;
}
.shop-listing .shop-hover .card-img-overlay {
display: none;
background: rgba(255, 255, 255, 0.5);
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
}
.shop-listing .shop-hover:hover .card-img-overlay {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.shop-listing .shop-hover .label {
padding: 5px 10px;
position: absolute;
top: 10px;
right: 10px;
}
/*******************
shop table
*******************/
.shop-table td {
padding: 30px 0;
}

Let’s register our routes in the app/app-routing.module.ts file :

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { CartComponent } from './components/cart/cart.component';
import { ProductsComponent } from './components/products/products.component';
const routes: Routes = [
{ path: '', component: ProductsComponent },
{ path: 'cart', component: CartComponent },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}

With this done we can now handle routing in our navbar component by defining the router links:

<nav class="navbar navbar-expand-lg navbar-light bg-info">
<div class="container">
<a routerLink="/" class="navbar-brand">Angular Cart</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a routerLink="/" class="nav-link">Home </a>
</li>
<li class="nav-item">
<a routerLink="/cart" class="nav-link">Cart </a>
</li>
</ul>
</div>
</div>
</nav>

We now can create some services that will handle our HTTP requests. To create a service in Angular, open up your terminal and type the following:

ng g s http

This will create a http.service.ts file. We will bring in the Angular HttpClient for making HTTP requests and then defining our HTTP services:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../environments/environment';
@Injectable({
providedIn: 'root',
})
export class HttpService {
constructor(private http: HttpClient) {}
getAllProducts() {
return this.http.get(`${environment.baseURL}/product`);
}
addToCart(payload) {
return this.http.post(`${environment.baseURL}/cart`, payload);
}
getCartItems() {
return this.http.get(`${environment.baseURL}/cart`);
}
increaseQty(payload) {
return this.http.post(`${environment.baseURL}/cart`, payload);
}
emptyCart() {
return this.http.delete(`${environment.baseURL}/cart/empty-cart`);
}
}

We store our server base in the environment.ts file:

baseURL: 'http://localhost:4000'

Let’s start with the products component, where we will be implementing the listing of products and adding product items to the cart.

To be able to use the Angular httpClient the module we have to register it globally in our application by importing it into our app/app.module.ts file:

import { HttpClientModule } from '@angular/common/http';
imports: [... other modules,HttpClientModule]

Let’s modify our codes in app/components/products.component.ts file to this:

import { Component, OnInit } from '@angular/core';
import { HttpService } from '../../http.service';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css'],
})
export class ProductsComponent implements OnInit {
products: Array<object> = [];
constructor(private http: HttpService) {}
_getProducts(): void {
this.http.getAllProducts().subscribe((data: any) => {
this.products = data.data;
console.log(this.products);
});
}
_addItemToCart( id, quantity): void {
let payload = {
productId: id,
quantity,
};
this.http.addToCart(payload).subscribe(() => {
this._getProducts();
alert('Product Added');
});
}
ngOnInit(): void {
this._getProducts();
}
}

And then setup our template for the application by editing the products.component.ts file to this:

<section>
<div class="spacer">
<div class="container">
<div class="row mt-5">
<div class="col-lg-9">
<div class="row shop-listing">
<div class="col-lg-4" *ngFor="let product of products">
<div class="card shop-hover border-0">
<img [src]="'http://localhost:5000/' + product.image" alt="wrapkit" class="img-fluid" />
<div class="card-img-overlay align-items-center">
<button class="btn btn-md btn-info" (click)="_addItemToCart(product._id, 1)">Add to Cart</button>
</div>
</div>
<div class="card border-0">
<h6>
<a href="#" class="link">{{ product.name }}</a>
</h6>
<h6 class="subtitle">by Wisdom</h6>
<h5 class="font-medium m-b-30">
${{product.price}}
</h5>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>

With this, we can now list all our products and also add product items to the cart.

We will proceed by implementing the cart section. Let’s define all our cart methods in the app/components/cart.component.ts file:

import { Component, OnInit } from '@angular/core';
import { HttpService } from '../../http.service';
@Component({
selector: 'app-cart',
templateUrl: './cart.component.html',
styleUrls: ['./cart.component.css'],
})
export class CartComponent implements OnInit {
carts;
cartDetails;
constructor(private http: HttpService) {}
_getCart(): void {
this.http.getCartItems().subscribe((data: any) => {
this.carts = data.data;
// this.cartDetails = data.data;
console.log(this.carts);
});
}
_increamentQTY(id, quantity): void {
const payload = {
productId: id,
quantity,
};
this.http.increaseQty(payload).subscribe(() => {
this._getCart();
alert('Product Added');
});
}
_emptyCart(): void {
this.http.emptyCart().subscribe(() => {
this._getCart();
alert('Cart Emptied');
});
}
ngOnInit(): void {
this._getCart();
}
}

And also set up a template for listing the cart items in the HTML file:

<section>
<div class="spacer">
<div class="container">
<div class="row mt-5">
<div class="col-lg-9">
<div class="row shop-listing">
<table class="table shop-table" *ngIf="carts">
<tr>
<th class="b-0">Name</th>
<th class="b-0">Price</th>
<th class="b-0">Quantity</th>
<th class="b-0 text-right">Total Price</th>
</tr>
<tr *ngFor="let item of carts.items">
<td>{{ item.productId.name }}</td>
<td>{{ item.productId.price }}</td>
<td>
<button class="btn btn-primary btn-sm" (click)="_increamentQTY(item.productId._id,1)">+</button>
{{ item.quantity }}
<button class="btn btn-primary btn-sm">-</button>
</td>
<td class="text-right">
<h5 class="font-medium m-b-30">{{ item.total }}</h5>
</td>
</tr>
<tr>
<td colspan="3" align="right">Subtotal :{{ carts.subTotal }}</td>
<td colspan="4" align="right">
<button class="btn btn-danger" (click)="_emptyCart()">Empty Cart</button>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</section>

Exercise

  • Implement the decrement feature
  • Implement removing products from the cart

After implementing this, Push your work to git and add the link in the comment section. Let's have some fun😁

--

--

Sunil Joshi
The Startup

Avid designer cum developer at WrapPixel.com who is passionate about solving complex UX challenges across digital businesses.