From Zero to CRUD in Angular: Part 1

Create, Read, Update, Delete (CRUD) pages

Many business application Web developers build Create, Read, Update, Delete (CRUD) pages in their day-to-day jobs. Over the years, you might have built these pages in Classic ASP, Web Forms, and MVC. You might have even used JavaScript, jQuery, and possibly AngularJS. It’s now, once again, time to learn how to build a CRUD page using Angular 4. In this series of articles you’ll start with an empty Web application, built using Vi- sual Studio 2015, and build up to a complete CRUD page.

In this rst part, you’re going to create a new Web project, add the appropriate Angular les, and display a simple page. You’re then going to create a Product table, build an Entity Framework data layer to retrieve data from that table, and create a Web API to call from Angular. You’ll nish by displaying a list of products on an HTML page by calling the Web API. You can see the nished HTML.

Set Up Your Computer

Before you begin to create an Angular application, you must prepare your development computer. There are two tools required: Node.js and Node Package Manager. In addition, you must con gure Visual Studio 2015 to use TypeScript. You should also get the Angular QuickStart project at

Install Node

If you haven’t done so already, download and install Node.js and NodeJS Package Manager (npm). You can get these two packages at

Follow the instructions for downloading and installing these tools on

Configure Visual Studio 2015

Most developers use TypeScript for Angular develop- ment. Ensure that you’ve downloaded and installed TypeScript 2.x for Visual Studio 2015. Select the Tools > Extensions and Updates menu to bring up the Exten- sions and Updates window (Figure 1) for Visual Studio. Click on the Installed node in the tree view and look through your list to see if you’ve installed TypeScript 2.x. If you have an older version of TypeScript, you need to update it.

To update to TypeScript 2.x, click on the Online node in the tree view and perform a search for TypeScript. Locate the latest version of TypeScript and download and install it into Visual Studio.

One last con guration item for Visual Studio is to select the Tools > Options menu and expand the Projects and Solutions node. Click on the External Web Tools (Figure 2). Ensure that the $(PATH) variable is located above any $(DevEnvDir) variables, if they exist, in your environment. If you don’t move this up, Visual Studio attempts to use its own tools instead of npm to update packages. In my installation of Visual Studio, these variables didn’t exist.

Install Angular Quick Start

Now that you’ve con gured Visual Studio, you’re going to need some con guration les and some TypeScript les to make it easier to get started with Angular. The Angular team has created a sample project that contains these les. This sample project is not a Visual Studio project, so you’re only going to use some of the les from this proj- ect and not bring all of them into your project. Download the quick start zip le from quickstart. After the zip le has downloaded, unzip the les into a folder on your hard drive.

Create Web Project for Angular

With your computer now appropriately con gured, let’s walk through the steps of creating and running your rst Angular application. This ensures that your environment is con gured correctly prior to trying to add the Web API and make HTTP calls.

Create a New Web Project

Start Visual Studio 2015 and select File > New > Project… from the menu. From the tree-view in the New Project win- dow (Figure 3), expand Templates > Visual C# > Web. Click on the Web node and from the list of templates, select the ASP.NET Web Application (.NET Framework). Set the Name of the new project to ProductApp. Click the OK button.

After clicking the OK button, you’re taken to a screen (Figure 4) that shows you a list of ASP.NET 4.5.2 Templates. Select the Empty Web project. You’re going to use the Web API to retrieve data from a SQL Server table, so check the Web API check box. Click the OK button and Visual Studio creates your new project.

Add Angular Files

Using Windows Explorer, navigate to the QuickStart les you downloaded earlier. Do NOT copy all of these les into your Visual Studio project because you don’t need all of them. Locate and copy the following les into the root of your new Visual Studio project.

  • • \bs-con g.json
  • • \package.json
  • • \tslint.json

Copy the whole folder \src into the root folder of your VS project.

Expand the \src folder and select the \app folder and all les within the folder. Right-mouse click and select the Include in Project menu. When you’re prompted to include the TypeScript typings, just answer No.

Restore Packages

Even though you’ve added an HTML page and some Type- Script les, nothing’s going to work yet. You need to download a whole new folder using the package manager utility (npm). Visual Studio can download all of these les using npm, but you must rst close and reopen Visual Studio. If you don’t close and reopen Visual Stu- dio, the appropriate menu item won’t show up. Go ahead and close your instance of Visual Studio now, and then reopen the ProductApp project. Right-mouse click on the package.json and select Restore Packages from the menu (Figure 5). This process takes a little while, so be patient.

After the installation of the packages is complete, click on the Show All Files icon in the Solution Explorer win- dow. A new folder has appeared named node_modules (Figure 6). DO NOT include this folder in your project. You don’t need all of these les. They’re just there to support the various libraries you use when developing with Angular.

At this point, you’re ready to test and see if you’ve hooked up everything correctly. Press F5, and if you have everything correct, you’ll see a page displayed in your browser

Add Bootstrap

To give your application a more professional appearance, add Twitter’s Bootstrap using the NuGet Package Man- ager. Right-mouse click on the ProductApp project and select Manage NuGet Packages… from the menu. Click on the Browse tab and search for “bootstrap.” Click the Install button to have Visual Studio download and add the appropriate les to your ProductApp project. Add the appropriate <link> and <script> tags to the index.html les by dragging and dropping them from your project folders into the <head> element. Be sure to put them in the following order.

<link href=”Content/bootstrap.min.css” rel=”stylesheet” />

<script src=”Scripts/jquery-1.9.1.min.js”> </script>
<script src=”Scripts/bootstrap.min.js”> </script>

Eliminate Hard-Coded

HTML Templates

In Figure 7, you saw the words “Hello Angular” appear. These words came from an HTML snippet contained in the app.component.ts le. I don’t like having HTML written in TypeScript, so I create an HTML page to display the HTML for the landing page of my Angular application.

Right-mouse click on the \app folder and select Add > HTML Page and set the name to app.component.html. Click the OK button. Remove the HTML in the page and replace it with the following:

<div class=”row”>
<div class=”col-xs-12″>

<h1>{{pageTitle}}</h1> </div>

In the HTML above, the value for a variable named pageTitle is going to be retrieved from the AppComponent


Figure 7: If you get to this page, your Angular installation is working.

class and displayed within an <h1> element. Open the \app\app.component.ts le and you’ll see the following declaration.

selector: ‘my-app’,
template: `<h1>Hello {{name}}</h1>`


Create, Read, Update, Delete (CRUD) pages

Now that you’ve created the new HTML page, you’re go- ing to remove the hard-coded HTML from the template property in the @Component decorator. Note that the template property uses the back-ticks and not apostro- phes for creating the hard-coded HTML template. If you wish to use hard-coded templates like this, you need to use the back-tick. I have found, however, that if you have any more than a few lines of HTML, this property becomes cumbersome to maintain. Let’s change the tem- plate property to the templateUrl property and set that property to the string ‘app.component.html’. Once you use a le name, you switch to using apostrophes.

Another change you’re making to this @Component decorator is adding the property moduleId and set- ting that property to the value This prop- erty helps Angular understand relative paths in rela- tion to the current component. If you didn’t use the moduleId property, you change the templateUrl prop- erty to ‘./app/app.component.html’. I prefer to use relative paths, as opposed to having to fully qualify the path in relation to the root.

The AppComponent class that came with the QuickStart sample has a name property set to the word ‘Angular’. The next snippet is the code in the app.component.ts le.

export class AppComponent { name = ‘Angular’;


In the app.component.html page you created, you changed the HTML to bind to a property called pageTitle. Remove the name property and add the pageTitle prop- erty, as shown in the following code snippet.

export class AppComponent {

pageTitle = ‘Product Application; }

The last thing to do is to modify the index.html to use the Bootstrap CSS. Add a <div> element immediately after the <body> element. Set the CSS class equal to “contain- er”. All other HTML pages in your Angular application are going to be loaded within the <my-app> directive, so you want them all to live within a Bootstrap container style.

<div class=”container”>

<p>Loading application…</p>

</my-app> </div>

If you run the application again, you’ll see the same page as before but now with the text Product Application.

How All of the Pieces Fit Together

Now that you have your Angular application up and run- ning, let’s look at the various les you added and how they relate to one another. In Figure 8, you can see an overview of all the HTML and TypeScript les you’ve worked with thus far.

The following numbers are a description of each of the numbers contained in Figure 8.

1. The application runs index.html, which runs the JavaScript System.import() function to load and run the code within the \app\main.ts le.

2. The code in main.ts imports the code from the app. module.ts le. The AppModule class, de ned in app. module.ts, is used as the “bootstrap” code to start the Angular application.

3. The AppModule class is empty, but what’s important is the @NgModule decorator to de ne various metadata for the module. The one you’re concerned with right now is the declarations property, which identi- es AppComponent class as the root component for the Angular application. The AppComponent class is de ned in the app.component.ts le. The app. component.ts le is imported at the top of the app. module.ts le.

  1. The AppComponent class has a @Component deco- rator that sets the selector property with a name of my-app. This selector is used as the HTML directive <my-app> on the index.html page. The my-app di- rective is associated with the AppComponent com- ponent, so it knows to look at the templateUrl prop- erty to identify the HTML page it needs to insert into the location of the <my-app> directive.
  2. The HTML in the app.component.html page is read and inserted into the index.html where the <my- app> directive is located.
  3. Prepare the Server-Side Code

    Now that you have your client-side Angular application work- ing, create a SQL Server table and code for your server-side. On the server-side, you need to create a table to hold prod- uct data, an Entity Framework data layer, and a Web API. In addition, you need to add some code in the Global.asax le to change the case of the C# property names to be camel- case to more closely match JavaScript coding standards.

    Create Product Table

    To create the page that lists product data (Figure 11), create a table called Product in a SQL Server database. In the following code snippet, you can see the full de nition of the Product table.

    Once you create the table, add some data to each eld. Create enough rows that you can see several rows on your nal HTML page. In Figure 9, you can see the data that I used to create the list of product data for this sample application.

    Build Entity Framework Model

    With your Product table in place, you need a data layer to be able to retrieve and modify the data in that table. Let’s use the Entity Framework code generator that’s built-into Visual Studio to create this data layer. This code generator allows you to list, add, edit and delete data from the Product table.

    Right-mouse click on the \Model folder and select Add > New Item… Click on the Data node and then select ADO. NET Entity Data Model from the list of templates. When prompted for the item name, type in ProductDB. Click the Add button to move to the next step in this process

    Select Code First from database and click the Next button to create a server connection. Create a new connection to the database where you installed the Product table. After creating the connection, leave everything else the same in this step of the wizard and click the Next button.

    Expand the tree view and locate the Product table you previously created. Click the Finish button to have Visual Studio create the Entity Framework data model for the Product table.

    After the Entity Framework generates the classes, you’ll have an entity class called Product that has the properties listed in the next snippet. I’m showing this class to you because you’re going to create a corresponding Angular Product class in TypeScript later in this article. Don’t add this class; it’s already there in the \Model folder.

    public class Product {

    public int ProductId { get; set; }
    public string ProductName { get; set; } public DateTime IntroductionDate { get; set; } public string Url { get; set; }
    public decimal Price { get; set; }


    Sample Code

    You can download the sample code for this article by visiting my website at downloads. Select PDSA Articles, and then select “CODE Magazine – From Zero to CRUD in Angular – Part 1” from the drop-down list.

    Create Web API

    To retrieve data from your Product table from within an Angular application or any client-side technology, you must create a Web API. Right-mouse click on the \Con- trollers folder and select Add > Web API Controller Class (v2.1) from the menu. Set the name to ProductCon- troller and click the OK button. Add a Using statement at the top of this controller le to include the namespace generated by the Entity Framework.

    using ProductApp.Models;

    Delete all of the code within this new controller class, as you’re going to write your Web API methods using a more updated approach than what’s generated by Visual Studio. Type in the code listed in the code snippet below to create a method that retrieves all products from the Product table.

    public IHttpActionResult Get() { IHttpActionResult ret; ProductDB db = new ProductDB();

    if (db.Products.Count() > 0) { ret = Ok(db.Products);

    } else {

    ret = NotFound(); }

    return ret; }

    Fix the Global.asax

    Earlier, I mentioned that the C# class Product is going to have a similar class created on the client-side that maps all properties one-to-one. However, the C# class uses pascal-casing of properties, and the TypeScript class is going to use camel-casing. You can add code to the Application_Start method in the Global.asax le to auto- matically convert properties from pascal-case to camel- case. Open the Global.asax le and at the top of the le add the two using statements shown in this code snippet.

    using Newtonsoft.Json.Serialization; using System.Net.Http.Formatting;

    Modify the Application_Start method to look like the code shown in Listing 1. The code you’re adding to the Application_Start method selects the current GlobalCon- guration.Con guration property and assigns it a vari- able called con g. The next line of code instructs the formatter to ignore any self-referencing objects in the Entity Framework. There aren’t any in this application, but this code can be useful when the Entity Framework generates more tables that have references to one an- other.

    The next line of code queries the Formatters collection and retrieves the rst instance of any JsonMediaTypeFor- matter object it nds. Finally, you create a new instance of a CamelCasePropertyNamesContractResolver and as- sign that to the formatter’s ContractResolver property. This property controls how the JSON objects are format- ted and sent to the client-side caller.

    Build Client-Side Product List

    Now that you have your server-side pieces in place and have gotten Angular to work in your project, you can start building the HTML and classes to create a list of products. You’re going to create a folder under the \app folder for each of your different pages. In this sample, you’re building a system for handling products, so you’re going to create a \product folder. If you add more pages to handle customers, you create a \customer folder, and so on. This helps you keep all of your different pages or- ganized. In this part of the article, there are four new les that you’re going to create. These four les are sum- marized in Table 1.




    A class that represents a single Product object


    A class to call the Web API to retrieve product data and return an array of Product objects


    The HTML needed to display the table of product data


    The class with properties and methods to display the product data

    Create Product Class

    As you’re going to retrieve a collection of Product class- es from the Web API, you need a Product class written in TypeScript. Add a new folder under the \app folder named \product. Right-mouse click on this new folder and select Add > TypeScript le from the context-sensi- tive menu. Give this new le the name of product.ts. Add the following code in this le.

    export class Product { productId: number; productName: string; introductionDate: Date; price: number;

    url: string;

    categoryId: number; }

    Notice that the structure of this class is exactly like the Product class that the Entity Framework generated. The only difference is the use of camel-case instead of pas- cal-case. Remember that you added code in the Global. asax to handle this conversion for you.

    Listing 1: Modify the Global.asax to automatically convert the casing of properties.

    protected void Application_Start() { GlobalCon guration.Con gure(WebApiCon g.Register);

    // Get Global Con guration

    HttpCon guration con g = GlobalCon guration.Con guration;

    // Handle self-referencing in Entity Framework

    con g.Formatters.JsonFormatter .SerializerSettings.ReferenceLoopHandling =



    // Convert to camelCase

    var jsonFormatter = con g.Formatters .OfType<JsonMediaTypeFormatter>()


    jsonFormatter.SerializerSettings .ContractResolver = new


    Listing 2: The product service retrieves a collection of products from your Web API.

    import { Injectable } from ‘@angular/core’; import { Http, Response } from ‘@angular/http’; import { Observable } from ‘rxjs/Observable’; import ‘rxjs/add/operator/map’;
    import ‘rxjs/add/operator/catch’;
    import ‘rxjs/add/operator/throw’;

    import { Product } from “./product”;

    export class ProductService {

    private url = “api/product”; constructor(private http: Http) {


    getProducts(): Observable<Product[]> { return this.http.get(this.url)

    .map(this.extractData) .catch(this.handleError);


    private extractData(res: Response) { let body = res.json();
    return body || {};


    private handleError(error: any): Observable<any> { let errors: string[] = [];

    switch (error.status) { case 404: // Not Found

    errors.push(“No Product Data Is Available.”); break;

    case 500: // Internal Error errors.push(error.json().exceptionMessage); break;

    errors.push(“Status: ” + error.status

    + ” – Error Message: ” + error.statusText);

    break; };

    console.error(‘An error occurred’, errors); return Observable.throw(errors);

    } }

    Create Product Service

    You need an Angular product service to call the Web API controller that you created earlier. This product service retrieves all products. Right-mouse click on the \app\ products folder and select New > TypeScript le from the menu. Set the name to product.service.ts and click the OK button. Add the code shown in Listing 2.

    Let’s break down the code in Listing 2. You rst import the various classes and functions you need for this ser- vice using the ‘import’ keyword.

    import { Injectable } from ‘@angular/core’; import { Http, Response } from ‘@angular/http’; import { Observable } from ‘rxjs/Observable’; import ‘rxjs/add/operator/map’;
    import ‘rxjs/add/operator/catch’;
    import ‘rxjs/add/observable/throw’;

    import { Product } from “./product”;

    The injectable class is needed to support the use of the @ Injectable decorator attached to the ProductService class. This decorator informs Angular that this class may be in- jected into the constructor of any component. The HTTP and Response classes are used to access the Web API and to retrieve the response from the Web API. Next, is the Observ- able import. You’re going to retrieve data using the Angular HTTP service. This service returns all calls from a Web API as an Observable object. Next are a series of imports that provide extension functions such as map, catch, and throw.

    These functions, as well as the Observable object, are supplied by RxJS or Reactive Extensions for JavaScript. You can learn more about these libraries at https:// The RxJS library helps you transform, compose, and query any type of

    data. In the ProductService class, you use it to take the result set of data you retrieve from the Web API and map it to an Angular Observable object.

    The last import is the Product class you created. Because you want to return an array of product objects returned from the Web API, you must import this class.

    Angular injects the HTTP service into the ProductService class. Any class marked with the @Injectable decorator may be injected into any class by declaring it in the con- structor. The HTTP service class, created by the Angular team, has been decorated with the @Injectable decorator.

    constructor(private http: Http) { }

    The next two functions in the class are getProducts and extractData. The getProducts function calls the Web API using the get function of the HTTP service. It creates a promise using the toPromise extension function. If data is retrieved, the then function is called and passed a ref- erence to the extractData function. You don’t really need the extractData function, but I like having this function as it makes it easy for to set a breakpoint and see the data that’s been returned. The extractData function is passed in the HTTP response object. Call the JSON function on this response object to retrieve the array of product data.

    getProducts(): Observable<Product[]> { return this.http.get(this.url)

    .map(this.extractData) .catch(this.handleError);


    private extractData(res: Response) { let body = res.json();

    return body || {}; providers: [ProductService] } })

    The last function in this class is handleError. This func- tion is used to publish the error information and return an Observable object with a string array of the errors re- turned from the call. I’m going to also output the error(s) to the console window of the browser. Use a switch/case statement so you can supply different error messages based on what’s returned from the Web API call. Inform the calling code of the error by passing the errors array to the throw function on the Observable class.

    Update the app.module.ts File

    In order to inject the HTTP service into the ProductSer- vice class, you need to import the HttpModule in the app. module.ts le. You then add this imported module to the @NgModule imports property. This makes it available for use in any of your classes. Angular takes care of injecting this service whenever it sees a reference to HTTP, as you saw in the constructor of your ProductService class.

    import { HttpModule } from ‘@angular/http’;

    imports: [BrowserModule, HttpModule ] …


    Remember that you marked your ProductService as an @ Injectable class. This means you want Angular to auto- matically inject this service into any of your class con- structors. To accomplish this, you also need to import the ProductService in your app.module.ts le and add this class to the providers property.

    import { ProductService }
    from “./product/product.service”;

    imports: [BrowserModule, HttpModule ], declarations: [ AppComponent ],

    Add the Product List HTML Page

    It’s now nally time to build the components needed to display a list of products like the page shown in Figure 11. Add a new HTML page named product-list.component. html to the \app\product folder. Remove all of the HTML in the new page and enter the HTML shown in Listing 3.

    In the HTML that builds the product table, use the *ngIf directive to test to see if there are any products. If there are, you build an HTML table using the *ngFor directive to iterate over a collection named products in the Pro- ductListComponent class. Each time through the loop, a product object is assigned to a local variable named prod- uct. Use this product variable to retrieve each property of the Product class and display the value of each in each cell of the table.

    At the end of the HTML, there’s another <div> element that displays any messages in an unordered list. You may receive errors if the call to the Web API failed for some reason, or maybe there was no data in the table. In that case, the messages property of the ProductListComponent class is lled in with an array of string messages to display.

    Create the Product List Component

    From the HTML in Listing 3, you know that your Pro- ductListComponent class (Listing 4) must expose two properties to the HTML page products and messages. This class must be injected with the ProductService class from which you can request the product data. This class must also have some exception handling in case the Web API throws an exception or doesn’t return data. Create the Pro- ductListComponent class by adding a new TypeScript le under the \app\product folder named ponent.ts. Write the code contained in Listing 4.

    Let’s look at each piece of the ProductListComponent class, and learn why you need each line of code and what each does. The rst step is to import the various classes you use within this class. The following four imports are used in this class.

    import { Component } from “@angular/core”; import { OnInit } from ‘@angular/core’;

    import { Product } from “./product”; import { ProductService }

    from “./product.service”;

    You can see the Component import is needed for the @ Component decorator. The templateUrl property in the decorator points to the product-list.component.html page that you just created.

    The OnInit import is an abstract class and isn’t absolutely necessary, but I like to use it to ensure that I type in the correct function name: ngOnInit. The ngOnInit function is a lifecycle event raised when the Angular engine cre- ates an instance of this class. Use the ngOnInit function to call the getProducts function to retrieve the product data from your product service class.

    The last two imports are easy to understand. You need the Product class because you’re going to ll an array of Product objects from your call to the product service. The constructor for this class receives the ProductSer- vice class from the Angular injection and assigns that instance to the private property named productService.

    private productService: ProductService) {


    Two properties are declared in this class: products and messages. The products property is an array of Product objects. Initialize this property to an empty array by us- ing the = []; syntax after the declaration of this prop- erty. The messages property is also a string array used to display any error messages on the page.

    // Public properties

    products: Product[] = []; messages: string[] = [];

    The getProducts function calls the getProducts function from the ProductService class. This function returns an

    <div class=”row”
    *ngIf=”products && products.length”>

    <div class=”col-xs-12″>
    <div class=”table-responsive”>

    <table class=”table table-bordered table-condensed table-striped”>

    <thead> <tr>

    <td>Product Name</td> <td>Introduction Date</td> <td>URL</td>
    <td class=”text-right”>Price</td>

    </tr> </thead> <tbody>

    <tr *ngFor=”let product of products”> <td>{{product.productName}}</td> <td>{{product.introductionDate | date }} </td>


    <td class=”text-right”>
    {{product.price | currency:’USD’:true }}

    </td> </tr>

    </tbody> </table>

    </div> </div>


    <div class=”row”
    *ngIf=”messages && messages.length == 0″>

    <div class=”col-xs-12″>
    <div class=”alert alert-warning”>

    <li *ngFor=”let msg of messages”>{{msg}}</li>

    </ul> </div>

    </div> </div>

    Listing 4: The product listing component.

    import { Component } from “@angular/core”; import { OnInit } from ‘@angular/core’;

    import { Product } from “./product”;
    import { ProductService } from “./product.service”;

    templateUrl: “./product-list.component.html”

    export class ProductListComponent implements OnInit {

    constructor(private productService: ProductService) { }

    ngOnInit(): void { this.getProducts();


    // Public properties

    products: Product[] = []; messages: string = [];

    private getProducts(): void { this.productService.getProducts()

    .subscribe(products => this.products = products, errors => this.handleError(errors));


    private handleErrors(errors: any): void { for (let msg of errors) {

    this.messages.push(msg); }

    } }

    Observable object, so you can use the subscribe func- tion to retrieve the product array and assign it to the products property in this class. If an error occurs when calling the Web API, the second parameter to subscribe is called. Take the error object passed back from the Prod- uctService and pass that to the handleError function in this class.

    getProducts(): void { this.productService.getProducts()

    products => this.products = products, errors => this.handleError(errors)


    The handleError function is passed into the array of er- rors from the call to the product service. This function loops through the errors array, extracts each message and pushes it onto the messages array. Because this messages property is bound to the unordered list on the product-list.component.html page, the error messages are displayed within that list.

    private handleErrors(error: any): void { for (let msg of errors) {

    this.messages.push(msg); }



    Update the app.module.ts File

    Just like you did with the other components that you added to the project, add the ProductListComponent class to the app.module.ts. Open the app.module.ts le and add an im- port near the top of the le that looks like the following:

    import { ProductListComponent }
    from “./product/product-list.component”;

    In the @NgModule decorator, add the ProductListCom- ponent class to the declarations property by adding a comma after AppComponent and typing in the name of this class as shown below:

    [ AppComponent, ProductListComponent ]

    Listing 5: The routing class de nes one or more routes for your application.

    import { NgModule } from ‘@angular/core’; import { RouterModule, Routes }

    from ‘@angular/router’; import { ProductListComponent }

    from “./product/product-list.component”;

    const routes: Routes = [ {

    path: ‘productList’,

    component: ProductListComponent }


    imports: [RouterModule.forRoot(routes)], exports: [RouterModule]

    export class AppRoutingModule { }

    Angular Routing

    No Angular application would be complete without rout- ing. Routing allows you to navigate from one page to an- other. The app.component.html page you created earlier is the main page for getting to other pages in this ap- plication. You’re going to add a router-outlet directive to this page. Add the following HTML below the other HTML on this component.

    <div class=”row”>
    <div class=”col-xs-12″>

    <a class=”btn btn-primary”

    routerLink=”/productList”> Product List

    </a> </nav> <br />

    <router-outlet></router-outlet> </div>


    The key pieces in the HTML above are the routerLink at- tribute in the anchor tag and the <router-outlet> direc- tive. The <router-outlet> directive tells Angular where to insert the HTML supplied by the component that’s routed to by the value in the routerLink attribute. It’s the value in this attribute, productList, that you’re going to match up with a route de ned in a TypeScript le called app- routing.module.ts. Add a new TypeScript le called app- routing-module.ts and add the code shown in Listing 5.

    The important part of the app-routing.module.ts le is the constant named routes. This constant contains an array of Route objects. Each object has a path property that’s used in the routerLink attribute you created earlier. If the path matches the address in the browser, the component prop- erty is used to instantiate an instance of the object listed in this property. Once this class is instantiated, the HTML de ned in that class’ templateUrl property is inserted into the location where the <router-outlet> directive is located.

    The route’s constant is added to the singleton instance of the Router service using the forRoot function. You can

    see this in the imports property of the @NgModule deco- rator. You can add as many routes to the routes constant as you need for your application.

    Overview of Angular Routing

    With all that description above, I thought a graphical representation of the Angular routing you’re using in this application might help clear things up a little. Here’s a description of each of the numbers you see in Figure 10.

    1. Anytimethebrowser’saddressbarisupdatedviaan anchor tag or other mechanism, the last part of the address is matched up to one of the routes added to the singleton instance of the Router service.
    2. Once Angular nds the path in the Router service, Angular instantiates the class listed in the compo- nent property.
    3. After the class is instantiated, the templateUrl property is read from the @Component decorator.
    4. The HTML from the le listed in the templateUrl property is loaded and inserted into the DOM at the location of the <router-outlet> directive.

    Update the app.module.ts File

    Declare your intention to use routing by importing it into the app.module.ts le. Open the app.module.ts le and add the following import statement near the top of the le.

    import { AppRoutingModule } from ‘./app-routing.module’;

    Add the AppRoutingModule to the imports property in the @NgModule decorator. The imports property should now look like the following code snippet.

    [BrowserModule, HttpModule, AppRoutingModule ]

    Run the Page

    At this point, you can run the page and see a list of the product data you entered into your Product table. If you entered the same data that I did, you should see a page that looks like Figure 11.


    Congratulations! You’ve successfully created your rst Angular application using Visual Studio. There are a lot of steps to get Angular up and running, but once you get the basics con gured, adding new pages and new com- ponents is quite easy because you use the same pattern that you learned in this article. In my next article, you’re going to add a detail page, select a single product from a Web API call, and then learn to add, edit, and delete a product.

    Read more about computers and programming here

Leave a Reply

Your email address will not be published. Required fields are marked *