DEV Community

Cover image for Build a Shopping Cart in Nodejs and Angular
Sunil Joshi
Sunil Joshi

Posted on • Edited on • Originally published at wrappixel.com

Build a Shopping Cart in Nodejs and Angular

In this article we are going to build shopping cart frontend 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 this tutorial.

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

cd desktop
mkdir angular-cart && cd angular-cart
ng new angular-cart
Enter fullscreen mode Exit fullscreen mode

Running the ng new 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 this 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 is an online template store where you could get great Angular Dashboard Template and Angular Material Themes.

We will create our components for 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
Enter fullscreen mode Exit fullscreen mode

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

We need to configure Bootstrap into our application by adding the CDN into 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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Shop Header

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 {}
Enter fullscreen mode Exit fullscreen mode

With this done we can now handle routing in our navbar component by define 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>
Enter fullscreen mode Exit fullscreen mode

Sponsored:

React


We can now 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
Enter fullscreen mode Exit fullscreen mode

This will create a http.service.ts file. We will bring in the Angular HttpClient for making http request and then define 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`);
  }
}
Enter fullscreen mode Exit fullscreen mode

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

baseURL: 'http://localhost:4000'
Enter fullscreen mode Exit fullscreen mode

We can now use this services in our component. We will start from the products component, where we will be implementing listing of products and adding of product items to cart.

To be able to use the Angular httpClient 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]
Enter fullscreen mode Exit fullscreen mode

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();
  }
}
Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

With this we can now list all our products and also add product items to 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();
  }
}
Enter fullscreen mode Exit fullscreen mode

And also setup 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>
Enter fullscreen mode Exit fullscreen mode

Shopping Cart

Exercise

  • Implement the decrement feature
  • Implement remove product from cart

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

Top comments (0)