Build a Shopping Cart in Nodejs and Angular
Tags: angular, webdev, javascript, beginners
Published: 2020-09-07 06:27:27

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](https://blog.wrappixel.com/building-a-shopping-cart-in-nodejs/?ref=232), which we already have published.

Note that you need to have the angular CLI installed on your local machine. To [upgrade to Angular](https://blog.wrappixel.com/angular-upgrade/?ref=232) 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

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](https://www.wrappixel.com/templates/wrapkit/?ref=232).

WrapPixel is an online template store where you could get great [Angular Dashboard Template](https://www.wrappixel.com/templates/category/angular-templates/?ref=232) and [Angular Material Themes](https://www.wrappixel.com/demos/angular-admin-templates/material-angular/landingpage/?ref=232).

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

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

We need to configure [Bootstrap](https://www.getbootstrap.com) 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>
    

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;
    }
    


![Shop Header](https://www.wrappixel.com/demos/images/shopping-cart-head-angular.png)



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 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>

---

### Sponsored:

[![React](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6be3k0c5qa8udbdbqcsx.jpg)](https://adminmart.com/templates/react/?ref=6)

---

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

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`);
      }
    }

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

    baseURL: 'http://localhost:4000'

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]


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 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 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>
```

![Shopping Cart](https://www.wrappixel.com/demos/images/cart-wrappixel-appliction.png)



## 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😁