Wednesday, June 27, 2018

A14–Building App using Angular and ASP.NET Core 2.1–Responsive Product Card and Shopping Cart

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13 Github Repo

Today’s post is again going to be brief. You might think that these posts are becoming boring and I don’t put more code. My goal is to work on this app just a little bit everyday and learn something everyday. I don’t get to spend a lot of time on this app since most of the time I am working late at night. Sometimes I might do a lot and sometimes not a whole lot. So my goal is just learn and share—even if it is one sentence that I watched a video.

I tried to make product card and shopping cart responsive. I added checkout-contact component and hooked up to checkout button. However, I didn’t implemented logic for collecting contact information. I am thinking of first completing entire navigation scenario of checkout process and then implement details of each page.

Alright that’s it. Checkout the code on github.

Tuesday, June 26, 2018

A13–Building App using Angular and ASP.NET Core 2.1–Updating Shopping Cart Quantity

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12 Github Repo

Today’s post is going to be brief. I added following functionality to Shopping Cart page.

When you increase quantity of any given product then,

1. Order sub total should get updated.

2. Order Quantity should be updated.

3. Cart total should be updated.

Since there is no database backend, I have to add extra logic to account for persistence. For example, to simulate accurate quantity and amount post deletion, I had to write custom server side logic. This is unnecessary once data store is in place.

image

After increasing quantity order sub total is updated.

image

There is one issue I am running into and that is when using ngModelChange on input element, the change event is firing twice which seems like bug to me or I am doing something wrong (I think later to be true).

That’s all for today, see ya next time.

Monday, June 25, 2018

A12–Building App using Angular and ASP.NET Core 2.1–Shopping Cart

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11 Github Repo

In the previous post, I started created Shopping Cart page where you could view products and remove products from Shopping Cart. Today, I want to fix a couple of things about Shopping Cart. If you added multiple products then we want to do following things.

1. Show Product along with quantity

2. Change Product quantity

3. Show Order Total

4. Update Order Total when product is deleted.

5. Do not show same product multiple times if product is ordered multiple times.

Below is the UI for new checkout experience.

image

If I remove product then order total is updated.

image

I created a complete different class for displaying products on Shopping Cart Page. I am calling it ShoppingCartProduct. In the ShoppingCartController, I am getting all products and then doing a group by into ShoppingCartProduct.

using A100.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;

namespace A100.Controllers
{
    [Route("api/[controller]")]
    public class ShoppingCartController : Controller
    {
        private static List<Product> shoppingCartProducts = new List<Product>() {
            new Product { Id = 1, Title = "XYZ1",Description = "Description XYZ 1 ", Price = 101,ImageUrl = "ImageUrl_XYZ1" },
            new Product { Id = 1, Title = "XYZ1",Description = "Description XYZ 1 ", Price = 101,ImageUrl = "ImageUrl_XYZ1" },
            new Product { Id = 1, Title = "XYZ1",Description = "Description XYZ 1 ", Price = 101,ImageUrl = "ImageUrl_XYZ1" },
            new Product { Id = 2, Title = "XYZ2",Description = "Description XYZ 2 ", Price = 200,ImageUrl = "ImageUrl_XYZ2" }
        };
        [HttpGet("[action]")]
        public IEnumerable<ShoppingCartProduct> Products()
        {
            var s = from y in shoppingCartProducts
                    group y by y.Id into grouping
                    let p = grouping.First()
                    select new ShoppingCartProduct { Id = grouping.Key,
                        Title = p.Title,
                        Quantity = grouping.Count(),
                        Price = p.Price,
                        Description = p.Description,
                        ImageUrl = p.ImageUrl,
                        TotalPrice = p.Price * grouping.Count() };
            return s.ToList();
        }

        [HttpPost("[action]/{id:int}")]
        public ActionResult Add(int id)
        {
            return new JsonResult("product added to cart");
        }
        [HttpPost("[action]/{id:int}")]
        public ActionResult Delete(int id)
        {
            return new JsonResult("product removed from cart");
        }
    }
}

I had to update relevant parts shopping-cart.component.ts as well.

That’s all I have for today. Please check source code on Github and ask questions if you have any.

Friday, June 22, 2018

A11–Building App using Angular and ASP.NET Core 2.1–Services and Component Refactoring

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 Github Repo

Yesterday, I added items to Shopping Cart and API to add products to Shopping Cart. Next step is to be able to checkout products from Shopping Cart and in order to do so I needed a page to display products in Shopping Cart. So Below are things, I was able to accomplish today.

1. Added Shopping Cart Component, Display Products in the cart, Remove products from Shopping Cart.

image

2. I added Shopping Module and Routing Module for that. Since after adding Shopping Module, I was running into issues related to ShoppingCartWidget component. NavMenu component was complaining that you have to declare in the main module. I moved ShoppingCartWidget component into Shared Folder and reference from there. I had to refactor little bit regarding that.

3. Added code to Shopping Service related to removing product from shopping cart.

There are couple of things, I wanted to share that I liked. I switch between VS Code and Visual Studio for this project and I am in love with VS Code. Today I installed few extensions for VS and it makes your job much easier. Below are the ones I use for Angular Development.

1. Angular 6 Snippets – Mikael Morlund

2. Angular Files – Alexander Ivanichev

3. Angular Language Service – Angular

4. Angular V6 Snippets – John Papa

5. Debugger for Chrome – Microsoft

6. TSLint – Egamma

7. SASS – Robin Bentley

Angular Language Service extension and snippets is by far my favorite one. But they all helped me a lot. VS Code is so light weight. I like it a lot.

On learning path I am intending on finishing below courses

1. Learning Angular Routing by Debora Kurata on Pluralsight

2. Implementing and Securing an API with ASP.NET Core by Shawn Wildermuth on Pluralsight

See ya next time. And leave comments if you like anything or have any suggestion.

Code on GitHub.

Thursday, June 21, 2018

A10–Building App using Angular and ASP.NET Core 2.1–Services, Events and Cross Component Communication

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9 Github Repo
Today, I was able to accomplish few things,
1. Added Shopping service that adds product and updates shopping cart
2. Established cross component communication via Shopping Service (Home Component –> Add To Cart –> Updates Shopping Cart
3. Created API for adding and getting products from ShoppingCart Controller. I am returning hard coded products and hence you will always see two shown at the top right.
Right now I didn’t wanted to create any database backend. I want to just make sure client server interaction is in sync. Once I like how everything is structured then I will invest time into adding database layer. Below is code for Shopping Service.
import { Injectable, Inject } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Product } from '../product/product';
import { catchError, map, tap,last } from 'rxjs/operators';
import 'rxjs/add/observable/throw';
import { of } from 'rxjs/observable/of';
import { Observable } from 'rxjs/Observable';
const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  })
};
@Injectable()
export class ShoppingService {

  private _baseUrl: string;
  private cartQuantitySource = new BehaviorSubject(0);
  currentCartQuantity = this.cartQuantitySource.asObservable();

  private _addProductToShoppingCart: string = "api/ShoppingCart/Add/";
  private _getProductsFromShoppingCart: string = "api/ShoppingCart/Products";
  constructor(private _http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    this._baseUrl = baseUrl;
    this.updateCartQuantity(); 
  }

  updateCartQuantity() {
    this._http.get<Product[]>(this._baseUrl + this._getProductsFromShoppingCart).subscribe(products => {
      this.log(`getting products from shopping cart`);
      this.cartQuantitySource.next(products.length);
    });
  }

  addProductToCart(product: Product) {
    this._http.post(this._baseUrl + this._addProductToShoppingCart + product.id, product, httpOptions).subscribe(x => {
      this.log(`added Product To Shopping Cart`);
      this.updateCartQuantity();
    });    
  }

  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.log(error); //log to console instead       
      this.log(`${operation} failed: ${error.message}`);
      return Observable.throw(error || 'Server error');
    };
  }
  private log(message: string) {
    console.log("Shopping Service " + message);
  }
}

One of the things, I am not liking is how api urls are hard coded as strings. This is something I want to improve upon. I will put them inside an injectable service which has all the urls.
Next thing I want to learn is authentication and authorization with ASP.NET Core.

Wednesday, June 20, 2018

A9–Building App using Angular and ASP.NET Core 2.1–Font-awesome, Pagination and Layout

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, Github Repo

Today, I got carried away with home page layout and wasn’t able to fix communication between components. I spent trying to add pagination using some blogpost but then I discovered ngx-pagination. Below are things I was able to do.

1. Added pagination using ngx-pagination npm package it was pretty straight forward

2. Added font-awesome npm package so I could add shopping cart icon.

3. Added pagination to home page and products page

4. Added shopping-cart-widget component for displaying cart information

image

Next, I want to fix communication between components, ie. when you click on add to cart button it should add items to cart and call server side api method.

See ya next time.

Tuesday, June 19, 2018

A8–Building App using Angular and ASP.NET Core 2.1–SASS and Responsive Layout

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, Github Repo

Today, I could accomplish very little.

1. Fixed cards layout for home page

I like to put borders and see how where the boxes are.

image

As we change screen size, we can see responsive design at work.

image

Another one

image

image

Alright I messed this one up, I want to make this look different. However, I am running out of time for today.

image

2. From the screenshots above, menu has been fixed and is also responsive.

3. Using SASS syntax was something new—you don’t have to put {} and ; and indentation like python. So I will have to get used to this syntax.

Next, I will have to continue fixing home page styling and then I will follow up on adding more product information. I am excited to work on server side logic.

See ya next time.