Ionic

Ionic 5 Shopping cart app

Share your learning

Hey buddy, Today we are going to build a shopping cart app with ionic 5. We will create the following things with this app.

  1. Products listing page
  2. My cart page
  3. Nav tabs
  4. Show products count for few seconds on listing page
  5. Add product to the cart and calculate amount
  6. Increase and decrease quantity
  7. 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.

Satpal

Recent Posts

How to Switch PHP Versions in XAMPP Easily: Managing Multiple PHP Versions on Ubuntu

Today we are going to learn about managing multiple PHP versions on ubuntu with xampp.…

1 year ago

How to Use Coding to Improve Your Website’s SEO Ranking?

Let's understand about how to use coding to improve your website's SEO. In today’s computerized…

1 year ago

Most Important Linux Commands for Web Developers

Let's understand the most important linux commands for web developers. Linux, as an open-source and…

1 year ago

Top 75+ Laravel Interview Questions Asked by Top MNCs

Today we are going to discuss top 75+ Laravel interview questions asked by top MNCs.Laravel,…

1 year ago

Mailtrap Integration for Email Testing with Laravel 10

Today we will discuss about the Mailtrap integration with laravel 10 .Sending and receiving emails…

1 year ago

Firebase Cloud Messaging (FCM) with Ionic 6: Push Notifications

Today we are going to integrate FCM (Firebase Cloud Messaging) push notifications with ionic application.Firebase…

1 year ago