Search Tutorials


Ecommerce Website - Online Book Store - Create Book Shopping Module | JavaInUse
     
 

   
   

Ecommerce Website - Online Book Store - Create Book Shopping Module

In this tutorial series we will be developing an ecommerce website for buying books. In a previous tutorial we created the book admin module to edit existing book details. In this tutorial we will be creating the book shopping module using which use can browse all the available books and add them to the shopping cart.

Ecommerce Website - Online Book Store using Angular 8 + Spring Boot

Ecommerce Website - Online Book Store using Angular 8 + Spring Boot Introduction Ecommerce Website - Online Book Store - Create Menu Module Ecommerce Website - Online Book Store - Create User Admin Module - Part 1 Ecommerce Website - Online Book Store - Create User Admin Module - Part 2 Ecommerce Website - Online Book Store - Create User Admin Module - Part 3 Ecommerce Website - Online Book Store - Create Book Admin Module - Part 1 Ecommerce Website - Online Book Store - Create Book Admin Module - Part 2 Ecommerce Website - Online Book Store - Create Book Admin Module - Part 3 Ecommerce Website - Online Book Store - Create Book Admin Module - Part 4 Ecommerce Website - Online Book Store - Create Book Shopping Module

Angular Code

Create a new component named shopbook
ng generate component shopbook


Next in the app routing module add a path for the shop book component
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { UsersComponent } from './admin/users/users.component';
import { BooksComponent } from './admin/books/books.component';
import { ShopbookComponent } from './shopbook/shopbook.component';


const routes: Routes = [
  { path: 'admin/users', component: UsersComponent },
  { path: 'admin/books', component: BooksComponent },
  { path: 'shop', component: ShopbookComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
In the menu.html add the menu option to show the shop book component
<header>
    <nav class="navbar navbar-expand-md navbar-dark bg-dark">
        <div><a href="https://www.javainuse.com" class="navbar-brand">JavaInUse</a></div>
       

        <ul class="navbar-nav">
            <li><a  class="nav-link" routerLink="/shop"  >Shop</a></li>
            <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown"
                    aria-haspopup="true" aria-expanded="false">
                    Admin
                </a>
                <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                    <a routerLink="/admin/users" class="dropdown-item">Users</a>
                    <a routerLink="/admin/books" class="dropdown-item">Books</a>
                </div>
            </li>
        </ul>
    </nav>
</header>
If we now go to localhost:4200 and select shop we can see the following

Next we will modify shop book component to display the list of books to the user. Modify the shopbook.component.ts as follows-
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClientService } from '../service/http-client.service';
import { Book } from '../model/Book';

@Component({
  selector: 'app-shopbook',
  templateUrl: './shopbook.component.html',
  styleUrls: ['./shopbook.component.css']
})
export class ShopbookComponent implements OnInit {

  books: Array<Book>;
  booksRecieved: Array<Book>;

  constructor(private router: Router, private httpClientService: HttpClientService) { }


  ngOnInit() {
    this.httpClientService.getBooks().subscribe(
      response => this.handleSuccessfulResponse(response),
    );
  }

  // we will be taking the books response returned from the database
  // and we will be adding the retrieved   
  handleSuccessfulResponse(response) {
    this.books = new Array<Book>();
    //get books returned by the api call
    this.booksRecieved = response;
    for (const book of this.booksRecieved) {

      const bookwithRetrievedImageField = new Book();
      bookwithRetrievedImageField.id = book.id;
      bookwithRetrievedImageField.name = book.name;
      //populate retrieved image field so that book image can be displayed
      bookwithRetrievedImageField.retrievedImage = 'data:image/jpeg;base64,' + book.picByte;
      bookwithRetrievedImageField.author = book.author;
      bookwithRetrievedImageField.price = book.price;
      bookwithRetrievedImageField.picByte = book.picByte;
      this.books.push(bookwithRetrievedImageField);
    }
  }
}
Next modify the shopbook html file to display the books using the bootstrap card css. A card is a flexible and extensible content container. It includes options for headers and footers, a wide variety of content, contextual background colors, and powerful display options.
<div class="container row">
    <div class="col-md-4" *ngFor="let book of books;let i=index">
        <div class="card card-block">
            <img class="custom-image-style" img src="{{book.retrievedImage}}" height="300" width="200" style="margin-left: 60px;
          margin-top: 10px">
            <div class="book-desc-container row">
                <div>
                    <p style="margin-left: 60px"><strong>{{book.name}}: ${{book.price}}</strong></p>
                    <p style="margin-left: 60px">{{book.author}}</p>
                </div>
                <div class="offset-md-4 col-md-4">
                    <button class="btn btn-primary btn-sm" (click)="addToCart(book.id)"
                       >Add To Cart</button>
                </div>
            </div>

        </div>
    </div>
</div>
If we now go to localhost:4200/shop-

In the book model class add another field named isAdded. This field will be used to identify if a book has been added to a shopping cart.
export class Book {
    id: number;
    name: string;
    author: string;
    price: number;
    picByte: string;   
    retrievedImage: string; 
    isAdded: boolean;
    }
Next we will be implementing the add book to cart functionality. For this we make use of Localstorage. Web storage objects - localStorage and sessionStorage allow to save key/value pairs in the browser. What is interesting about them is that the data survives a page refresh (for sessionStorage) and even a full browser restart (for localStorage).
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClientService } from '../service/http-client.service';
import { Book } from '../model/Book';

@Component({
  selector: 'app-shopbook',
  templateUrl: './shopbook.component.html',
  styleUrls: ['./shopbook.component.css']
})
export class ShopbookComponent implements OnInit {

  books: Array<Book>;
  booksRecieved: Array<Book>;

  cartBooks: any;

  constructor(private router: Router, private httpClientService: HttpClientService) { }


  ngOnInit() {
    this.httpClientService.getBooks().subscribe(
      response => this.handleSuccessfulResponse(response),
    );
    //from localstorage retrieve the cart item
    let data = localStorage.getItem('cart');
    //if this is not null convert it to JSON else initialize it as empty
    if (data !== null) {
      this.cartBooks = JSON.parse(data);
    } else {
      this.cartBooks = [];
    }
  }

  // we will be taking the books response returned from the database
  // and we will be adding the retrieved   
  handleSuccessfulResponse(response) {
    this.books = new Array<Book>();
    //get books returned by the api call
    this.booksRecieved = response;
    for (const book of this.booksRecieved) {

      const bookwithRetrievedImageField = new Book();
      bookwithRetrievedImageField.id = book.id;
      bookwithRetrievedImageField.name = book.name;
      //populate retrieved image field so that book image can be displayed
      bookwithRetrievedImageField.retrievedImage = 'data:image/jpeg;base64,' + book.picByte;
      bookwithRetrievedImageField.author = book.author;
      bookwithRetrievedImageField.price = book.price;
      bookwithRetrievedImageField.picByte = book.picByte;
      this.books.push(bookwithRetrievedImageField);
    }
  }

  addToCart(bookId) {
    //retrieve book from books array using the book id
    let book = this.books.find(book => {
      return book.id === +bookId;
    });
    let cartData = [];
    //retrieve cart data from localstorage
    let data = localStorage.getItem('cart');
    //prse it to json 
    if (data !== null) {
      cartData = JSON.parse(data);
    }
    // add the selected book to cart data
    cartData.push(book);
    //updated the cartBooks
    this.updateCartData(cartData);
    //save the updated cart data in localstorage
    localStorage.setItem('cart', JSON.stringify(cartData));
    //make the isAdded field of the book added to cart as true
    book.isAdded = true;
  }

  updateCartData(cartData) {
    this.cartBooks = cartData;
  }

  goToCart() {
    this.router.navigate(['/cart']);
  }

  emptyCart() {
    this.cartBooks = [];
    localStorage.clear();
  }

}
Next we will be modifying the shop book html file to display the shopping cart functionality.
<div class="container row">
    <div class="col-md-2">
        <h1>Books</h1>
    </div>
    <div class="col-md-10 custom-products-cart-container">
        <div class="offset-md-8">
            <ul class="nav navbar-nav navbar-right">

                <li class="dropdown">
                    <br>
                    <a href="#" class="btn btn-info btn-lg" data-toggle="dropdown" role="button" aria-expanded="false">
                        <span class="fa fa-shopping-cart">
                            Books Added In Cart:
                        </span>
                        <span class="caret">{{cartBooks.length}}</span>
                    </a>
                    <ul class="dropdown-menu dropdown-cart" role="menu">
                        <li *ngFor="let item of cartBooks">
                            <div class="item product-cart-item row">
                                <div class="col-md-8" *ngIf="item">{{item.name}}</div>
                                <div class="col-md-4" *ngIf="item"><strong>${{item.price}}</strong></div>
                            </div>
                        </li>
                        <hr>
                        <li><a class="btn btn-small btn-success" role="button" (click)="goToCart()">View Cart</a></li>
                        <br>
                        <li *ngIf="cartBooks.length > 0">
                            <a class="btn btn-small btn-warning" role="button" (click)="emptyCart()">Empty Cart</a></li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
</div>

<hr>
<hr>


<div class="container row">
    <div class="col-md-4" *ngFor="let book of books;let i=index">
        <div class="card card-block">
            <img class="custom-image-style" img src="{{book.retrievedImage}}" height="300" width="200" style="margin-left: 60px;
          margin-top: 10px">
            <div class="book-desc-container row">
                <div>
                    <p style="margin-left: 60px"><strong>{{book.name}}: ${{book.price}}</strong></p>
                    <p style="margin-left: 60px">{{book.author}}</p>
                </div>
                <div class="offset-md-4 col-md-4">
                    <button class="btn btn-primary btn-sm" (click)="addToCart(book.id)"
                        [disabled]="book.isAdded===true">Add To Cart</button>
                </div>
            </div>

        </div>
    </div>
</div>
If we now go to localhost:4200/shop, we can add the books to cart. We can also empty the cart.

Download Source Code

Download it -
Spring Boot + Ecommerce
Angular8 Online Book Store

See Also

Spring Boot Hello World Application- Create simple controller and jsp view using Maven Spring Boot Tutorial-Spring Data JPA Spring Boot + Simple Security Configuration Pagination using Spring Boot Simple Example Spring Boot + ActiveMQ Hello world Example Spring Boot + Swagger Example Hello World Example Spring Boot + Swagger- Understanding the various Swagger Annotations Spring Boot Main Menu Spring Boot Interview Questions