Ionic 5 Shopping cart app
Hey buddy, Today we are going to build a shopping cart app with ionic 5. We will create the following things with this app.
- Products listing page
- My cart page
- Nav tabs
- Show products count for few seconds on listing page
- Add product to the cart and calculate amount
- Increase and decrease quantity
- Basic Slider on the product listing page
Live Demo
So, Let’s start
Create a shopping cart project with ionic 5
You can check the ionic installation process on ionic official docs.
ionic start shopper tabs --type=angular
It will create the ionic app with name shopper and template tabs. We are using ionic-angular for this app.
Generate ionic 5 service
It will add the products service inside the services/products directory. If we don’t use sub-directory for products service then our service will create inside the services directory which can be mixed with other services. So, we are trying to separate all services in the sub-directories.
Product service
ionic generate service services/products/products
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class ProductsService { show_result_size: boolean = true; bannerImages = [ { imgurl: 'assets/images/slide1.jpg' }, { imgurl: 'assets/images/slide2.jpg' }, { imgurl: 'assets/images/slide3.jpg' } ]; products = [ { id : 1, imgurl: 'assets/images/slide1.jpg', name: 'Multi color bags', category: 'shopping', price: 67, totalStock: 10 }, { id : 2, imgurl: 'assets/images/slide3.jpg', name: 'Daily use bags', category: 'routine', price: 37, totalStock: 10 }, { id : 3, imgurl: 'assets/images/slide2.jpg', name: 'Real Value', category: 'folk', price: 77, totalStock: 10 }, { id : 4, imgurl: 'assets/images/slide1.jpg', name: 'Vosto bags', category: 'shopping', price: 65, totalStock: 10 } ]; categories : any = [ { category : 'shopping' }, { category : 'folk' }, { category : 'routine' } ]; constructor( ) { } initProductList() { this.showResultCount(); } showResultCount() { this.show_result_size = true; setTimeout(() => { this.show_result_size = false; }, 2000); } }
Product service will manage product listing, filtering, sorting etc. In this article we are going to perform listing only. In the next part we will add product filtering and sorting too.
Cart Service
ionic generate service services/cart/cart
import { Injectable } from '@angular/core'; import { UtilityService } from '../utility/utility.service'; @Injectable({ providedIn: 'root' }) export class CartService { items: any = []; item: any; total_price: number = 0; total_cart_qty:number = 0; unseen: number = 0; constructor( private utility: UtilityService) { } placeItem(product) { this.item = null; this.item = product; } isAddedToCart(id) { return this.items.some(item => item['id'] == id ); } getCartTotalQty() { console.log(this.items); this.total_cart_qty = 0; for (let item of this.items) { this.total_cart_qty += item['cartQuantity']; } } addToCart() { if ( this.item['cartQuantity'] > 0 ) { this.addLocalCartItems(); } } increaseCartQty(index) { //this.utility.presentLoading('Add quantity...'); let increasedQty = this.items[index]['cartQuantity'] + 1; if ( increasedQty <= this.items[index]['totalStock'] ) { this.increaseLocalCartItem( index ); this.getCartTotalQty(); } else { //this.utility.dismissLoading(); this.utility.showToast("More Stock is not available!", "top"); } } decreaseCartQty(index) { //this.utility.presentLoading('Decrease quantity...'); let decreasedQty = this.items[index]['cartQuantity'] - 1; if ( decreasedQty >= 1 ) { this.decreaseLocalCartItem( index ); this.getCartTotalQty(); } else { //this.utility.dismissLoading(); this.utility.showToast("Quantity can't be less than Min order Quantity", "top"); } } removeItem(index) { this.removeLocalCartItem(index); } /* Handle cart locally with below methods */ increaseLocalCartItem(index) { this.items[index]['cartQuantity'] += 1; this.total_price += this.items[index]['price']; } decreaseLocalCartItem(index) { this.items[index]['cartQuantity'] -= 1; this.total_price -= this.items[index]['price']; } removeLocalCartItem(index) { this.total_price -= this.calculatePrice(this.items[index]); this.items.splice(index, 1); } addLocalCartItems() { this.unseen += 1; console.log('add to cart>:', this.items, this.item); let index = this.items.length > 0 ? this.items.findIndex(value => value.id === this.item.id) : -1; if ( index > -1 ) { console.log(this.items[index]['cartQuantity'], this.item['cartQuantity']); this.items[index]['cartQuantity'] += this.item['cartQuantity']; } else { this.items.push(this.item); } } totalPrice() { this.total_price = 0; for ( let item of this.items ) { this.total_price += this.calculatePrice(item); } } calculatePrice(product) { let price = product['price']; return Number(product['cartQuantity']) * Number(price); } resetCart() { this.items = []; this.item = null; } }
Cart service will manage all cart related things like place item to a cart, add item with updated quantity to the cart items, remove item from the cart and increase/decrease cart items quantity.
Generate Add to cart page
ionic generate page pages/add-to-cart
We will use this page as a modal to add the product to the cart and increase/decrease product quantity while adding product to the cart. Once it will add the product to the cart, we can update the product quantity from the cart page.
import { Component, OnInit } from '@angular/core'; import { ModalController } from '@ionic/angular'; import { CartService } from 'src/app/services/cart/cart.service'; import { UtilityService } from 'src/app/services/utility/utility.service'; @Component({ selector: 'app-add-to-cart', templateUrl: './add-to-cart.page.html', styleUrls: ['./add-to-cart.page.scss'], }) export class AddToCartPage implements OnInit { minOrderQty: any; availableQty: any; constructor( private modalCtrl: ModalController, public cart: CartService, public utility: UtilityService ) { this.minOrderQty = 1; this.cart.item['cartQuantity'] = this.minOrderQty; this.availableQty = this.cart.item['totalStock'] || 0; } ngOnInit() { } dismiss() { this.modalCtrl.dismiss(); } increaseQuantity() { let itemQty = this.getCartItemQty(); let increasedQty = itemQty + 1; if (increasedQty <= this.availableQty) { this.cart.item['cartQuantity'] += 1; } else { this.utility.showToast(`This Stock is not available!`, 'top', 'error'); } } decreaseQuantity() { let itemQty = this.cart.item['cartQuantity']; let decreasedQty = itemQty - 1; if (decreasedQty >= this.minOrderQty) { this.cart.item['cartQuantity'] -= 1; } else { this.utility.showToast(`Minimum order quantity is ${this.minOrderQty}`, 'top', 'error'); } } getCartItemQty() { let index = this.cart.items.findIndex(value => value.id === this.cart.item.id); let qty = this.cart.item['cartQuantity']; if ( index > -1 ) { qty = this.cart.items[index]['cartQuantity'] + this.cart.item['cartQuantity']; } return qty; } addToCart() { let itemQty = this.getCartItemQty(); let validOrder = this.availableQty > 0 && itemQty <= this.availableQty; if ( validOrder ) { this.cart.addToCart(); this.modalCtrl.dismiss(); } else { this.utility.showToast('This product is out of stock!', 'top', 'error'); } } }
Create a product listing page
Go to src/app/tabs and change the tab names to Home, Cart and Account etc. Then we are using a cart unseen badge over the cart tab icon.
We are hiding the labels here, because the icon will be enough. Now, open the src/app/tab1 page directory and go to tab1.page.ts file.
import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { IonRouterOutlet, ModalController } from '@ionic/angular'; import { AddToCartPage } from '../pages/add-to-cart/add-to-cart.page'; import { CartService } from '../services/cart/cart.service'; import { ProductsService } from '../services/products/products.service'; @Component({ selector: 'app-tab1', templateUrl: 'tab1.page.html', styleUrls: ['tab1.page.scss'] }) export class Tab1Page { // set app banner slides slideOpts = { initialSlide: 0, speed: 400, loop: true, autoplay: { delay: 4000, disableOnInteraction: false, } }; bannerImages: any = []; products: any = []; constructor( public productService : ProductsService, public routerOutlet : IonRouterOutlet, public modalCtrl : ModalController, public cart : CartService, private router: Router ) { this.bannerImages = this.productService.bannerImages; this.products = this.productService.products; } async addToCartModal(item) { console.log('item_id :>> ', item); let isAdded = this.cart.isAddedToCart(item.id); if ( !isAdded ) { this.cart.placeItem(item); const modal = await this.modalCtrl.create({ component: AddToCartPage, cssClass: 'add-to-cart-modal', presentingElement: this.routerOutlet.nativeEl }); await modal.present(); await modal.onWillDismiss().then((result) => { console.log('result :>> ', result); }).catch((err) => { console.log('err :>> ', err); }); } else { this.router.navigate(['/tabs/tab2']); } } }
We are using ionic slides here which use swiper.js for basic sliders. Then we have imported the product service here to list all the available products. We are using static data here but you can also fetch these products via APIs.
If you want an API based tutorial, please let me know in the comments. I will update this article with API integration.
So, When anything happens to products in the product service it will automatically update everywhere in the application.
When a user clicks on the Add to cart button it will assign the current product to the cart service item variable.
Now, this item is ready for a cart. But before that we can add some quantity to it. So, to do so we have added an add-to-cart modal page. When the user clicks on the add to cart button it will open this modal to update the quantity.
On this modal user can update quantity and click on the Done button. Now, the product is finally added to a cart.
Create a Cart page
Let’s create a cart page. Open src/app/tab2, this is a cart page. Here we have imported a cart service and in the ionViewWillEnter
we will update the cart total quantity and cart total amount.
import { Component } from '@angular/core'; import { CartService } from '../services/cart/cart.service'; @Component({ selector: 'app-tab2', templateUrl: 'tab2.page.html', styleUrls: ['tab2.page.scss'] }) export class Tab2Page { constructor( public cart : CartService, ) {} ionViewWillEnter() { this.cart.unseen = 0; this.cart.getCartTotalQty(); this.cart.totalPrice(); } placeOrder() { } }
In the cart service we have both methods of total quantity and total amount. To get these we just need to iterate all the cart items and calculate the quantity of each item, same thing for price.
getCartTotalQty() { console.log(this.items); this.total_cart_qty = 0; for (let item of this.items) { this.total_cart_qty += item['cartQuantity']; } } totalPrice() { this.total_price = 0; for ( let item of this.items ) { this.total_price += this.calculatePrice(item); } }
We have used total_price
and total_cart_qty
variables in the cart page and both variables are coming from cart service. So, these will update simultaneously as we update the items in the cart.
That’s it, a basic shopping cart with ionic 5.
Hope you enjoy the tutorial. All source code is free of cost and link given above with live demo.