Sunday, June 10, 2018

A1–Building App using Angular and ASP.NET Core 2.1

This post is a part of a series of posts that I will write as I build an app using Angular and ASP.NET Core 2.1. My goal with this series is not to show you how to do something but to build something little everyday and write about it. If I don’t build anything then I don’t write about it. I believe in concept of learn via building and learn via sharing. So let’s combine these two concepts. Please expect lots of mistakes being made by me and I hope you will correct them.

I have lot of experience building apps using AngularJS and ASP.NET MVC 5 but I wanted to learn Angular latest and ASP.NET Core 2.1. What I have done so far in this journey is listed below, so you have some background and you don’t assume that I am smart.

1. Watched Angular: Getting Started course on Pluralsight by Deborah Kurata

2. Finished Angular Tutorial: Tour of Heroes

3. Watching Angular: Forms course on Pluralsight by Mark Zamoyta

4. Built an app to showcase products and stuff.

My environment looks like this

1. Visual Studio 2017 15.7.3

2. Powershell

3. VS Code Latest

4. ASP.NET Core 2.1

5. Angular cli version listed below

image

6. Angular versions 5.2.0

I wanted to have server side back-end technology as ASP.NET Core and wanted to combine Angular with it. In latest ASP.NET Core 2.1, there is a template for getting started with this type of thing.

image

After application project was created, I was excited and I wanted to create a new Angular component. I executed this command on the command line ng generate component product-list and got the friend message to run npm install first. So I ran npm install and then did ng generate component product/product-list and used to get some errors. I don’t recall. However, after deleting contents of node_modules folder it started working.

Tip: Don’t run npm install. Just click Run or hit F5 and let visual studio install all dependencies.

In earlier version of ASP.NET Core 2.0 runtime, creating components using Angular CLI wasn’t that straight forward. In 2.1 working with Angular Cli has been fixed. I like this.

By default when you run the application, you get counter page and fetch data page. The fetch data page shows you how to retrieve data from ASP.NET WEB API endpoint.

I want to create product related pages such as insert, edit, delete, list, details and use ASP.NET WEB API. So first I created Product controller and related methods for doing insert, edit, delete, list and details. I used attribute routing. For simplicity, I am not connecting it to any database. I just want working methods. Then I tested these methods using PostMan client. Below is my Product Controller.

 [Route("api/[controller]")]
    public class ProductController : Controller
    {
        private static List<Product> Products = new List<Product>() {
            new Product { Id = 1, Title = "XYZ1", Price = 1,ImageUrl = "ImageUrl_XYZ1" },
            new Product { Id = 2, Title = "XYZ2", Price = 2,ImageUrl = "ImageUrl_XYZ2" },
            new Product { Id = 3, Title = "XYZ3", Price = 3,ImageUrl = "ImageUrl_XYZ3" },
            new Product { Id = 4, Title = "XYZ4", Price = 4,ImageUrl = "ImageUrl_XYZ4" },
            new Product { Id = 5, Title = "XYZ5", Price = 5,ImageUrl = "ImageUrl_XYZ5" },
            new Product { Id = 6, Title = "XYZ6", Price = 6,ImageUrl = "ImageUrl_XYZ6" },
            new Product { Id = 7, Title = "XYZ7", Price = 7,ImageUrl = "ImageUrl_XYZ7" },
            new Product { Id = 8, Title = "XYZ8", Price = 8,ImageUrl = "ImageUrl_XYZ8" },
            new Product { Id = 9, Title = "XYZ9", Price = 9,ImageUrl = "ImageUrl_XYZ9" }
            
        };
        [HttpGet("[action]")]
        public IEnumerable<Product> List()
        {
            return Products;
        }

        [HttpGet("[action]/{id:int}")]        
        public ActionResult<Product> Find(int id)
        {
            var product = Products.Where(x => x.Id == id).FirstOrDefault();
            if (product != null)
            {
                return product;
            }
            return NotFound($"Product with id {id} was not found");
        }

        [HttpPost("[action]")]
        public ActionResult<Product> Edit([FromBody] Product product)
        {
            return product;
        }

        [HttpPost("[action]/{id:int}")]
        public ActionResult<Product> Delete(int id)
        {
            return Ok("Delete Successfull");
        }

        [HttpPost("[action]")]
        public ActionResult<Product> Insert([FromBody] Product product)
        {
            return product;
        }
    }

Next up, I tried to create product-list angular component using angular cli using command ng g c product/product-list. I wanted to create product related component inside product folder. Hence, I used product/product-list as my component’s name. I am just going to borrow code from fetch-data component to retrieve product list.

import { Component, OnInit, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {
  public products: Product[];
  constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    http.get<Product[]>(baseUrl + 'api/Product/List').subscribe(result => {
      this.products = result;
    }, error => console.log(error));
  }
  ngOnInit() {
  }
}
interface Product {
  id: number;
  title: string;
  price: number;
  imageUrl: string;
}

Next up, I hooked up navigation and you can see all the products being displayed. For brevity, I am not listing all the steps or code. I am going to put all this on GitHub so you can see the code and progress I make. Because, it turns out blogging every step is going to be time consuming. [edit- Github Repo here]

image

Creating angular components for delete, details, edit and insert as shown below.

image

image

Creating edit, delete, details, insert action buttons on product-list html page and adding routerLink so we can take appropriate actions. Below is how the page looks now.

Tip: Route should not have any ending /. Have product/insert instead of product/insert/

image

I hooked up these buttons with their respective components created in earlier step. Right now I have not created an markup for these individual action pages. That’s all I could get done today.

Next goal is to put this on GitHub and finish creating insert, edit, delete, details features of products page. See you next time. [edit- Github Repo here]