Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

May 11, 2016

Angular 2: Getting Started with Visual Studio 2015 using a Web Site

My “Angular 2: Getting Started” course on Pluralsight details how to get started with Angular 2. To provide guidance that works on any platform (Windows, OS X, and Linux), the course uses Visual Studio Code as the editor. However, there are many developers that prefer to use Angular 2 with Visual Studio 2015.

The biggest challenge in providing guidance for using Angular 2 with Visual Studio 2015 is that there are too many options as outlined in this prior post. This post focuses on using Angular 2 with Visual Studio 2015 using a Web site instead of a Visual Studio project.

For this technique, we’ll cover how to set up and run the “Angular 2: Getting Started” files using the ‘Open Web Site’ feature of Visual Studio 2015.

1. Download the starter files from my GitHub repo: https://github.com/DeborahK/Angular2-GettingStarted

    If you are not familiar with using GitHub, just click on the “Download ZIP” button as shown below. Then unzip the files.

image_thumb3

2. Copy the files from the ‘APM – Start’ folder to a folder that has no spaces.

NOTE: The full path to the project.json file must have no spaces for these steps to work.

3. Open Visual Studio 2015 and select: File | Open | Web Site.

4. Select the folder created in step #2.

    This opens the Angular application as a Web site and automatically installs all of the packages.

5. Open the Output window (View | Output) to watch the npm command execute. When it is finished, you should see something like this:

image-9.png (712×368)

NOTE: There is an intentionally missing component (because we have not created it yet!). When running in VS Code, the application runs even though this component is missing. In Visual Studio 2015, the compile will fail and the application won’t run. To successfully compile the code, open main.ts and comment out the contents of this file. (Just be sure to uncomment them after we build the app.component.)

6. Open the Package Manager Console (View | Other Windows | Package Manager Console)

7. Type ‘npm start’ into the Package Manager Console.

NOTE: If there are any spaces in the path, the ‘npm start’ will not execute successfully.

This will launch your default browser and watch for changes. You can then edit any of the project files (AND SAVE!). The browser will then update automatically and reflect your changes.

NOTE: If the Package Manager Console does not appear to be in the correct directory for the ‘npm start’ command to work (it must be in the directory containing the package.json file), you can change the current path used by the Package Manager Console by typing this at the PM> prompt:

set-location -path .\APM -PassThru

This changes your current path to the APM subfolder. The -PassThur option displays the current path so you can confirm it.

By following the above steps, you can follow along with the course using Visual Studio 2015 instead of VS Code. Just be sure to follow steps 6 & 7 above each time you reopen the project to restart the script that watches for changes and refreshes the browser.

It would be great to hear from you on whether these steps worked for you. Follow me on twitter: @deborahkurata

Enjoy!

Angular 2: Getting Started with a Visual Studio 2015 TypeScript Project

My “Angular 2: Getting Started” course on Pluralsight details how to get started with Angular 2. To provide guidance that works on any platform (Windows, OS X, and Linux), the course uses Visual Studio Code as the editor. However, there are many developers that prefer to use Angular 2 with Visual Studio 2015.

The biggest challenge in providing guidance for using Angular 2 with Visual Studio 2015 is that there are too many options as outlined in this prior post. This post focuses on using Angular 2 with a Visual Studio 2015 TypeScript project.

For this technique, we’ll cover how to set up and run the “Angular 2: Getting Started” files using a TypeScript project in Visual Studio 2015.

1. Download the starter files from my GitHub repo: https://github.com/DeborahK/Angular2-GettingStarted

    If you are not familiar with using GitHub, just click on the “Download ZIP” button as shown below. Then unzip the files.

image_thumb3

2. Open Visual Studio 2015 and create a new project: File | New | Project.

3. Select the TypeScript project template and name the project “APM” for Acme Product Management.

image_thumb7

4. This creates several TypeScript sample files. Delete app.css, app.ts, and index.html.

image_thumb10

5. In file explorer, open the cloned or unzipped `APM – Start` folder if you want to start with the project starter files. Open the `APM – Final` folder if you want to work with the final files from the course.

image_thumb13

image_thumb16

6. Copy all of the files from within the folder shown above (except the .vscode folder) to the APM project file you just created with Visual Studio.

image_thumb20

7. Click the “Show All Files” button in the toolbar of Solution Explorer.

image_thumb27

8. Select to include the api and app folders and the index.html, package.json, tsconfig.json, and typings.json files into the project. If desired, click “Show All Files” again to hide the remaining files.

image_thumb33

9. Right-click on the package.json file and select: Restore Packages

image_thumb36

10. Open the Output window (View | Output) to watch Visual Studio 2015 run npm and install Angular 2 and its dependencies.

So even through we are using a Visual Studio 2015 menu option (Restore Packages), Visual Studio is running the Node Package Manager (npm) to install all of the packages defined in the package.json file.

image_thumb40

11. If npm finishes successfully, it should appear like this (see below) in the Output window.

image_thumb43

12. Right-click on index.html and select Set As Start Page.

image_thumb46

NOTE: There is an intentionally missing component (because we have not created it yet!). When running in VS Code, the application runs even though this file is missing. In Visual Studio 2015, the compile will fail and the application won’t run. To successfully compile the code, open main.ts and comment out the contents of this file. (Just be sure to uncomment them after we build the app.component.)

13. Press F5 to run and the application appears in the selected browser.

HOWEVER … you won’t be able to edit and continue. And if you edit and try to refresh the browser, you will most likely see a 404 message.

I have not yet figured out the magic required to provide edit and continue using Visual Studio 2015 directly … but you can get edit and continue if you stop debugging and run the application using a script instead of F5 following these additional steps:

14. Display the Package Manager Console (View | Other Windows | Package Manager Console).

15. Type `cd APM` in the Package Manager Console to change to the directory containing the APM project.

NOTE that if you used a different directory name for your project, type that instead. And if you have a space in the name, it will need to be enclosed in quotes: cd “APM – Start”

16. Type ‘npm start’ into the Package Manager Console.

This will launch your default browser and watch for changes. You can then edit any of the project files (AND SAVE!). The browser will then update automatically and reflect your changes.

By following the above steps, you can follow along with the course using Visual Studio 2015 instead of VS Code. Just be sure to follow steps 14-16 above each time you reopen the project to restart the script that watches for changes and refreshes the browser.

It would be great to hear from you on whether these steps worked for you. Follow me on twitter: @deborahkurata

Enjoy!

Angular 2: Getting Started with a Visual Studio 2015 ASP.NET 4.x Project

My “Angular 2: Getting Started” course on Pluralsight details how to get started with Angular 2. To provide guidance that works on any platform (Windows, OS X, and Linux), the course uses Visual Studio Code as the editor. However, there are many developers that prefer to use Angular 2 with Visual Studio 2015.

The biggest challenge in providing guidance for using Angular 2 with Visual Studio 2015 is that there are too many options as outlined in this prior post. This post focuses on using Angular 2 with a Visual Studio 2015 ASP.NET 4.x project.

NOTE: If you don’t want to follow all of these steps, you can download the “Angular 2: Getting Started” starter files for an ASP.NET 4.x project in Visual Studio 2015 here: https://github.com/DeborahK/Angular2-GettingStarted and use the “APM – Start VS 2015 ASP 4x” folder. The only step required below is then Step #2, downloading and installing the latest TypeScript tools for Visual Studio 2015. When you first open the provided solution, the packages will install/update automatically.

To manually set up and run the “Angular 2: Getting Started” files using a ASP.NET 4.x project in Visual Studio 2015, follow these steps:

1. Download the Angular 2 starter files from my GitHub repo: https://github.com/DeborahK/Angular2-GettingStarted

    If you are not familiar with using GitHub, just click on the “Download ZIP” button as shown below. Then unzip the files.

image

2. Open Visual Studio 2015 and download the latest set of TypeScript tools for Visual Studio. Open Tools | Extensions and Updates and search for TypeScript. Select the latest TypeScript version (1.8.4 shown below). Then install the downloaded package.

image

3. Create a new project: File | New | Project, select the ASP.NET project template and name the project “APM” for Acme Product Management.

image

4. Select the desired ASP.NET 4.x template. I selected the empty template with no MVC, no authentication and no hosting.

image

5. Copy the files from the APM – Start folder that was downloaded from my GitHub repo (see Step #1) to the APM folder containing the APM.csproj folder.

image

6. Select the Show All Files button in Solution Explorer to show all of the files.

image

7. Right-click on each folder/file to be included in the project (as shown below) and select ‘Included in Project’.

NOTE: You may see a dialog that asks if you want to search for TypeScript Typings. Select ‘No’.

image

8. Right-click on packages.json and select ‘Restore Packages’. This uses npm to install all of the packages defined in the package.json file. (Similar to typing ‘npm install’ at a command line prompt.)

image

9. Open the Output window (View | Output) to watch the npm command execute. When it is finished, you should see something like this:

image

NOTE: If you are using Angular 2 RC or higher and see errors here, such as: “‘angular/compiler’ is not in the npm registry”, your Visual Studio 2015 is most likely using an older version of npm. To correct this. Use Tools | Options | Projects and Solutions | External Web Tools and move the $(PATH) entry above the $(DevEnvDir) entries as shown below.

image

10. Refreshing Solution Explorer, you should then see a node_modules and typings folders as hidden folders for the project.

image

11. There is one additional option in the tsconfig.json file that is not required when using VS Code or some of the other editors, but is required if using Visual Studio 2015. Add this line to the tsconfig.json file: “compileOnSave” = true and SAVE.

image

You may have better results at this point if you exit Visual Studio 2015 and reopen it.

12. Click the Run button or press F5 to run the application.

This will launch your default browser and run the application. You can then edit any of the project files (AND SAVE!). Then refresh the browser to see your changes. NOTE: The refresh only works when there is no routing path in the address bar.

13. If you see errors on compilation such as “Property ‘map’ does not exist on type ‘Observable<Response>’” or “Observable cannot be found”, then exit Visual Studio and follow the instructions here: https://github.com/Microsoft/TypeScript/issues/8518

This involves replacing your C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TypeScript.typescriptServices.js file. NOTE: This requires admin privileges.

By following the above steps, you can follow along with the course using Visual Studio 2015 instead of VS Code.

It would be great to hear from you on whether these steps worked for you. Follow me on twitter: @deborahkurata

Enjoy!

April 28, 2016

Angular 2: Getting Started With Visual Studio 2015

My “Angular 2: Getting Started” course on Pluralsight details how to get started with Angular 2. To provide guidance that works on any platform (Windows, OS X, and Linux), the course uses Visual Studio Code as the editor. However, there are many developers that prefer to use Angular 2 with Visual Studio 2015.

The biggest challenge in providing guidance for using Angular 2 with Visual Studio 2015 is that there are too many options.

  • Do we use TypeScript? If so, do we use a TypeScript project in Visual Studio 2015?
  • Do we use a simple “Web Site”?
  • Do we use ASP.NET? If so, ASP.NET version 4.6 (current version) or ASP.NET Core 1.0 (previously known as ASP.NET version 5.0 and currently in beta)
  • Do we use MVC? If so, MVC 5 (current version) or MVC 6 (currently in beta)?
  • Do we use more JavaScript-ish tools such as npm? Or try to do everything with Visual Studio tools?
  • Do we use the command line? Or try to do everything within the Visual Studio 2015 IDE?
  • And so on …

The plan is to cover several of these options, starting with the most basic steps required to use Visual Studio 2015 with Angular 2.

Here are the links to the options covered so far:

Enjoy!

April 4, 2016

“Angular 2: Getting Started” Problem Solver

Filed under: Angular 2,JavaScript @ 12:25 pm
Tags: , ,

This blog post supports the sample code for the “Angular 2: Getting Started” course on Pluralsight, providing common issues along with their solutions. This includes issues migrating to newer releases of Angular 2. The course “as is” supports up to Angular 2 Beta 15.  If using a newer Beta or the release candidate (RC), please see the notes below.

The sample code can be found here: https://github.com/DeborahK/Angular2-GettingStarted. The folders in this repo include:

  • APM – Start: The starter files. Use this as a starting point to code along with the course.
  • APM – Start VS 2015 ASP 4x: The starter files set up for Visual Studio 2015 using an ASP.NET 4.x project. Use this as a starting point to code along with the course using Visual Studio 2015. (NOTE: This won’t exactly match the demos in the course.)
  • APM – Final: The completed files, updated to Angular 2 Beta 15. This code matches with the demos presented in the course.
  • APM – Final Updated: The completed files, updated to Angular 2 RC 1. This code includes breaking changes and noted in this blog post.

Please post to the Discussion tab for the course if you experience an issue not found in this post. Thanks!

 

Setting Up Behind a Corporate Web Proxy

Problem: The error you may see is: “Unable to read typings for es6-shim” when using `npm install`.

Solution 1: npm may not be using your globally defined proxy setting. Try adding a .typingsrc file with the value: "proxy=http://myproxy.com:myport"

Solution 2: Try manually installing the typings by running the following command at the command prompt: `npm run typings install`

See these posts for more information:

NOTE: If you do not have access to the proxy URL and port, you can install the missing typing manually following the steps posted in the comments for this post below.

 

“My First Component” Never Appears

Problem: After building the app.component and using npm start, the “Loading the app…” appears but the page title and “My First Component” never appears.

Solution: Be sure that the template is surrounded with back ticks (`) NOT a single quote (‘):

template: `
     <div><h1>{ {pageTitle} }</h1>
            <div>My First Component</div>
     </div>
`

 

Failed to Load Resource (favicon.ico)

Problem: The sample application loads and runs fine, but there is an error in the console that states: “Failed to load resource: the server responded with a status of 404 (Not Found)”. The file that is not found is listed as favicon.ico.

image

Solution: No favicon.ico file was provided with the sample application. If desired, add one to the root folder to resolve this 404 error.

 

Currency Pipe Does Not Work

Problem: The Angular 2 Currency pipe does not work in some browsers, such as Safari.

Solution: This is an internationalization issue and there is a work around as follows:

1. Install the international package: npm install intl@1.1.0 –save

2. Include the following in index.html:

  <– International Support –>
  <script src="node_modules/intl/dist/Intl.min.js"></script> 
  <script src="node_modules/intl/locale-data/jsonp/en.js"></script>

[[As provided by Amal Sudama on the discussion board for this course.]]

 

Custom Filter Pipe Has Errors (>= Angular Beta 16)

Problem: The signature of the transform function required to implement a custom pipe was changed in Angular Beta 16. The second argument to the transform method was an array of strings and starting in Beta 16 it is now a variable number of arguments.

The error you may see is: “Property ‘toLocaleLowerCase’ does not exist on type ‘string[]’”. Or you may see other TypeScript type errors.

Solution: Change the transform function from this:

OLD productFilter.pipe.ts

transform(value: IProduct[], args: string[]): IProduct[] {
    let filter: string = args[0] ? args[0].toLocaleLowerCase() : null;
    return filter ? value.filter((product: IProduct) =>
        product.productName.toLocaleLowerCase().indexOf(filter) !== -1) : value;
}

To this:

NEW productFilter.pipe.ts

transform(value: IProduct[], filter: string): IProduct[] {
    filter = filter ? filter.toLocaleLowerCase() : null;
    return filter ? value.filter((product: IProduct) =>
        product.productName.toLocaleLowerCase().indexOf(filter) !== -1) : value;
}

This change is *only* required if you are using Angular Beta 16 or newer.

 

Template Parse Warnings (>= Angular Beta 17)

Problem: There is a warning in the console that states: “Template parse warnings: ‘#’ inside of expressions is deprecated”.

This is due to a change in the *ngFor directive in Angular Beta 17. Instead of a local variable defined with ‘#’, the *ngFor directive uses the ES 2015 ‘let’ keyword. The result is a statement much more similar to the ES 2015 for/of construct.

image

Solution: Change the *ngFor directive syntax to use ‘let’ instead of ‘#’ as follows:

Change this:

OLD product-list.component.html

<tr *ngFor=’#product of products | productFilter:listFilter’>

To this:

NEW product-list.component.html

<tr *ngFor=’let product of products | productFilter:listFilter’>

This change is *only* required if you are using Angular Beta 17 or newer.

 

Cannot find module ‘angular2/core’ (>= Angular RC 0)

Problem: After typing `npm start`, the command window displays multiple errors including: ”Cannot find module ‘angular2/core’. The browser console displays “Failed to load resource: the server responded with a status of 404 (Not Found)” on files including angular2/core.

The first release candidate of Angular 2 repackaged all of Angular into individual packages, one per each feature area. All of the packages are now distributed using the @angular npm scoped package. This changes how Angular is installed via npm and how code is imported.

For the list of all Angular 2 packages, see this link.

This basically means two things:

  1. Many of the starter files have changed.
  2. All of the import statements that import Angular must be changed.

Solution: Here are the steps:

  1. Get the new starter files either from the updated repository for this course or from the Angular 2 Quick Start repository.
  2. Delete the current node-modules and typings folders.
  3. Re-run `npm install`
  4. Change every import statement that imports from an Angular library to use the new scoped package syntax.

Change this:

import { Component } from ‘angular2/core’;

To this:

import { Component } from @angular/core’;

These changes are *only* required if you are using Angular RC 0 or newer.

 

Problems with the Component Router (>= Angular RC 0)

Problem: Routing now generates errors such as “Module ‘"c:/Users/Deborah/Documents/GitHub/Angular2-GettingStarted/APM/node_modules/@angular/router/index"’ has no exported member ‘RouteConfig’.

This is because the component router has several breaking changes in Angular RC.

Solution: The quickest way to resolve this issue is to use the deprecated router:

import { ROUTER_PROVIDERS, RouteConfig, ROUTER_DIRECTIVES } from ‘@angular/router-deprecated‘;

These changes are *only* required if you are using Angular RC 0 or newer.

 

Migrating to the New Component Router (>= Angular RC 0)

Problem: After the move to Angular RC, you may want to migrate to the new component router.

Solution: The key breaking changes to note when moving to the new component router are:

1. RouteConfig is now Routes:

import { ROUTER_PROVIDERS, Routes, ROUTER_DIRECTIVES } from ‘@angular/router‘;

2. Routes no longer have a name property:

@Routes([
    { path: ‘/welcome’, component: WelcomeComponent },
    { path: ‘/products’, component: ProductListComponent },
    { path: ‘/product/:id’, component: ProductDetailComponent }
])

3. Routes don’t currently have a useAsDefault property (this may yet be implemented). For now, define a default route using ‘/’:

@Routes([
   { path: ‘/’, component: WelcomeComponent },
    { path: ‘/welcome’, component: WelcomeComponent },
    { path: ‘/products’, component: ProductListComponent },
    { path: ‘/product/:id’, component: ProductDetailComponent }
])

NOTE: If you define routes in a component whose template does not use a routerLink directive, the Router must be injected into the component. Otherwise the routes don’t work. The following example shows a template with a router-outlet but no routerLink.

@Component({
    selector: ‘pm-app’,
    template: `
    <div class="container">
        <h1>{{pageTitle}}</h1>
        <router-outlet></router-outlet>
     </div>
    `,
    directives: [ROUTER_DIRECTIVES],
    providers: [ROUTER_PROVIDERS]
})
@Routes([
    { path: ‘/’, component: ProductListComponent }
])
export class AppComponent {
    pageTitle: string = ‘Acme Product Management’;

    constructor(private router: Router) {}
}

4. Since routes no longer have names, every routerLink directive needs to change to use the path instead of the name:

<li><a [routerLink]="[‘/welcome‘]">Home</a></li>
<li><a [routerLink]="[‘/products‘]">Product List</a></li>

5. Route parameters are now defined as simple properties, not objects:

<td> <a [routerLink]="[‘/product’, product.productId]">
    {{product.productName}}
    </a>
</td>

6. Get the route parameters using the router’s OnActivate lifecycle hook instead of the component’s OnInit lifecycle hook, and using the current route segment:

import { Component } from ‘@angular/core’;
import { Router, OnActivate, RouteSegment } from ‘@angular/router’;

import { IProduct } from ‘./product’;
import { ProductService } from ‘./product.service’;
import { StarComponent } from ‘../shared/star.component’;

@Component({
    templateUrl: ‘app/products/product-detail.component.html’,
    directives: [StarComponent]
})
export class ProductDetailComponent implements OnActivate {
    pageTitle: string = ‘Product Detail’;
    product: IProduct;
    errorMessage: string;

    constructor(private _productService: ProductService,
                private _router: Router) {
    }

   routerOnActivate(curr: RouteSegment): void {
       let id = +curr.getParam(‘id’);
       this.getProduct(id);
   }

    getProduct(id: number) {
        this._productService.getProduct(id)
            .subscribe(
            product => this.product = product,
            error => this.errorMessage = <any>error);
    }

    onBack(): void {
        this._router.navigate([‘/products‘]);
    }

}

These changes are *only* required if you are using Angular RC 0 or newer.

 

Implementing Product Detail: Undefined Product

Problem: When implementing the product detail page, it generates an undefined exception such as “TypeError: Cannot read property ‘prodcutName’ of undefined”.

Solution: This problem occurs because the view is displayed prior to retrieval of the data. To prevent this error, add the following to the product-detail.component.html file:

<div class=’panel panel-primary’ *ngIf=’product’>

This prevents display of the view until the product is retrieved and populated.

 

Twitter Bootstrap Does Not Work Properly

Problem: If you add component features to the sample application using Twitter Bootstrap, they may not work properly. For example, if you add the Twitter Bootstrap styles to display a dropdown menu, the menu does not drop down.

Solution: To keep the sample application focused on the basics of Angular 2, I only added the Twitter Bootstrap styles, not its components. To use any of the Twitter Bootstrap components (such as a dropdown menu), you need jQuery and the Bootstrap JavaScript library

1. Modify the package.json file to include: "jquery": "2.2.3" (or whichever version you require)

2. Use the following command to update the packages: npm update

3. Include the following in index.html:

  <!–  Support Bootstrap Components –>
  <script src="node_modules\jquery\dist\jquery.min.js"></script>
  <script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>  

[[As provided by Scott Simpson on the discussion board for this course.]]

Enjoy!

Why Angular? Why Angular 2?

Filed under: Angular 2,JavaScript @ 10:52 am
Tags: , ,

Why Angular and not some other JavaScript framework? (And there are lots of JavaScript frameworks out there!)

image

· Angular makes our HTML more expressive. It powers up our HTML with features such as if conditions, for loops and local variables.

· Angular has powerful data binding. We can easily display fields from our data model, track changes, and process updates from the user.

· Angular promotes modularity by design. Our applications become a set of building blocks, making it easier to create and reuse content.

· And Angular has built-in support for communication with a back-end service. This makes it easy for our Web applications to integrate with a backend service to get and post data or execute server-side business logic.

No wonder Angular is so very popular with Web developers!

With so many developers already using Angular 1, why do we need an Angular 2?

image

· Angular 2 is built for speed. It has faster initial loads, faster change detection and improved rendering times.

· Angular 2 is modern. It takes advantage of features provided in the latest JavaScript standards and beyond such as classes, modules, and decorators. And it leverages Web Component technologies for building reusable user interface widgets. Yet it supports both green field and legacy browsers: Edge, Chrome, Firefox and Internet Explorer back to IE 9!

· Angular 2 has a simplified API. It has fewer built-in directives to learn, simpler binding, and a lower overall concept count.

· And Angular 2 enhances our productivity to improve our day-to-day workflow by providing a consistent pattern for writing our code.

For more information on Angular 2, check out my “Angular 2: Getting Started” course from Pluralsight.

Angular 2: Getting Started

Filed under: Angular 2,JavaScript @ 10:43 am
Tags: , ,

Whether you are new to Angular or new to Angular 2, you’re going to want to come up to speed quickly with Angular 2’s components, templates, and services. My latest Pluralsight course “Angular 2: Getting Started” provides the basics you need to get started building an Angular 2 application.

image

The course covers the following topics:

image

o We start with first things first. We’ll select a language and editor to use. Then walk through how to set up an Angular 2 application.

o Next we’ll dive into components. We’ll build the App component using a simple template and minimal component code and metadata. Here the focus is on the code including the what, why, and how.

o We’ll see how to build the user interface for our application using templates, interpolation, and directives.

o We’ll power up that user interface with data binding and nicely format our data with pipes.

o Next we’ll tackle some additional component techniques. We’ll define interfaces, encapsulate styles, and leverage lifecycle hooks to build better components.

o We’ll see how to build a component designed to be nested within other components. And how to communicate between the nested component and its container.

o We often have logic or data that is needed across components. We’ll learn how to build services specifically for this purpose and use dependency injection to inject those services into the components that need them.

o Most Web applications need to communicate with a back-end server to get or post data and to execute back-end business logic. In this module, we’ll leverage http and observables to retrieve the data for our application.

o Our sample application displays multiple views. We’ll see how to set up routing to navigate between those views.

We’re covering a lot of territory. And by the end of our journey, we’ll have a simple, but fully operational Angular 2 application that you can use as a reference for your own development.

Enjoy!

February 24, 2016

Understanding C# Delegates

Filed under: C#,LINQ @ 12:10 pm
Tags:

Delegates are sometimes seen as an ethereal concept, bodiless and hard to grasp. But they don’t have to be that way.

In my latest Pluralsight course: “C# Best Practices: Collections and Generics“, I walk through what a delegate is and how to understand them.

image

A delegate is simply a type that represents a reference to a method with a specific parameter list and return type. The primary purpose of delegates is to pass methods as arguments to other methods.

Here is an example of a method that needs a delegate:

var filteredList = vendors.Where(???);

In the above line of code, we use the LINQ Where method to filter a list of vendors. The Where method needs a selector defining the logic to be used for the filtering. Do we want to filter the list of vendors by some keyword in their name? Or by how much they currently owe us? Or by the product types that they sell? Somehow we need to specify this logic. We do that with a method.

What does that method need to look like? In Visual Studio, Intellisense shows us the signature of the delegate method that it needs. For the LINQ Where method, it is:

vendors.Where(Func<Vendor, bool> predicate)

Let’s break down what Intellisense is telling us here:

  • The “Func” specifies that the method we create has to return a value. If the method does not require a return value, the Intellisense will instead say “Action”.
  • The first generic parameter (Vendor in this example) is the first parameter to the method we create.
  • If there is a return value, the last generic parameter (bool in this example) defines the return value type.

So looking at the example, we know we need to create a method with a bool return value that takes one parameter of type Vendor.

We can then create a method such as this:

private bool FilterCompanies(Vendor v)
{
   return v.CompanyName.Contains(“Toy”);
}

This method takes in a Vendor object and returns a Boolean. Specifically, it returns true if the vendor’s company name contains “Toy”. Otherwise it returns false, thereby specifying how we want the vendor list filtered.

We can then pass this method as a delegate to the Where method:

var filteredList = vendors.Where(FilterCompanies);

The resulting filteredList contains the list of vendors whose company name contains “Toy”.

The problem with this approach is that we end up with little methods all over that simply define these delegates. There is another way. We can use Lambda Expressions. Lambda Expressions are basically a short cut syntax for these little methods.

So instead of this:

var filteredList = vendors.Where(FilterCompanies);

private bool FilterCompanies(Vendor v)
{
   return v.CompanyName.Contains(“Toy”);
}

We can simply type this:

var filteredList = vendors.Where(v => v.CompanyName.Contains(“Toy”));

For more information, check out: “C# Best Practices: Collections and Generics” from Pluralsight.

Enjoy!

January 28, 2016

C# Best Practices: Collections and Generics

Filed under: C#,Lambda Expressions,LINQ @ 12:27 pm

The next in my series of “Best Practices” courses was published today in the Pluralsight library: “C# Best Practices: Collections and Generics“.

This course starts with the classic collection type: arrays. Then it moves on to generics … that challenging to explain topic that often shows up even in the most basic of beginner courses … because without generics we don’t have a good way to work with collections of things. And most applications require working with collections of things.

image

We move on to cover generic lists and generic dictionaries. Then we dive deeper into generic collections, looking at the interfaces they implement and how to leverage those interfaces as method parameters and return types.

image

Lastly, we look at Language Integrated Query (or LINQ) for filtering, shaping, ordering, grouping, aggregating, or locating elements in a collection. Along the way we cover extension methods, delegates, and Lambda expressions.

image

Enjoy!

January 26, 2016

Creating a Filter Pipe in Angular 2

Filed under: Angular 2,AngularJS @ 4:23 pm
Tags: ,

Angular 1.x has filters. Angular 2 has pipes, which fulfill a similar purpose. However, there are some key filters in Angular 1.x, such as the “filter filter”, that don’t have an equivalent Angular 2 feature. This post details how to build a filter pipe in Angular 2.

Angular 1.x

In Angular 1.x, we define an input box for a user to enter filter text. We then filter a list of items by that text with one simple clause as shown below:

<div class=”row”>
    <div class=”col-md-2″>Filter by:</div>
    <div class=”col-md-4″><input type=”text” ng-model=”listFilter” /></div>
</div>

<div class=”table-responsive”>
    <table class=”table”>
        <tbody>
            <tr ng-repeat=”movie in vm.movies | filter : {title:listFilter}“>
                <td>{{ movie.title}}</td>
                <td>{{ movie.director }}</td>
                <td>{{ movie.mpaa | uppercase}}</td>
            </tr>
        </tbody>
    </table>
</div>

Easy breezy.

Angular 2

Angular 2 provides pipes for this same purpose. But with no “filter” pipe in Angular 2, we have to build our own pipe component.

Converting the above code into Angular 2 results in:

<div class=”row”>
    <div class=”col-md-2″>Filter by:</div>
    <div class=”col-md-4″><input type=”text” #listFilter (keyup)=”0″ /></div>
</div>

<table class=”table”>
    <tbody>
        <tr *ngFor=”#movie of movies | movieFilter:listFilter.value” >
             <td>{{ movie.title}}</td>
            <td>{{ movie.director }}</td>
            <td>{{ movie.mpaa | uppercase}}</td>
        </tr>
    </tbody>
</table>

Hmmm. That does not look that different!

A few things you’ll notice here:

  • The local variable, listFilter, is now prefixed with a hash symbol (#) to explicitly identify it as a local variable.
    • This variable defines an HTML element, so to obtain the value, we need to access listFilter.value.
  • The (keyup)=”0″ syntax sets up an event listener for the keyup event. There is no event handler needed for this event, so it is just set to “0”.
  • The filter clause is defined here as movieFilter and we are filtering on the value of the listFilter variable. So our custom pipe is used just like the built-in pipes.

The key is creating the movieFilter pipe. In Angular 1.x, the “filter filter” was built in. In Angular 2, there are some built-in filters, but not a general list filter. So we need to build our own.

The purpose of a pipe is to take in a value, filter that value, and return the filtered result. In this example, the value we are taking in is a list of movies. We filter the movies to only those with a title containing the user-entered text. And we return the filtered result.

Here is the code for the movieFilter. The description follows.

import {Pipe, PipeTransform} from ‘angular2/core’;

@Pipe({
    name: ‘movieFilter’
})
export class MovieFilterPipe implements PipeTransform {

    transform(value: any, args: string[]): any {

       let filter = args[0].toLocaleLowerCase();
       return filter ? value.filter(movie=> movie.title.toLocaleLowerCase().indexOf(filter) != -1) : value;
    }
}

1) First we import the Pipe and PipeTransform. This is required to build any pipe.

2) We define a Pipe decorator. This tells Angular that this code is a pipe component. And we give the pipe a name: movieFilter. This is the name used in the HTML as part of a template expression.

3) We create a class that provides the processing for our pipe. We export the class so it can be imported by our movie component. And we implement the PipeTransform interface for our tooling. Note that implementing this interface is optional. With the @Pipe decorator, Angular already expects to find a transform method.

4) The PipeTransform interface requires implementing a transform method. This method has two parameters:

  • value: The value being filtered. In our example, this is the list of movies.
  • args: An optional array of parameters, one for each parameter passed to the pipe. In our example, we are passing listFilter.value.

5) We then define a result array which will contain the movies that match the filter criteria.

6) We create a variable to hold the passed in parameter. We use toLocaleLowerCase() so that the filtering won’t be case sensitive.

7) We check the filter variable. If there is no filter defined, we simply return the original value. No need to iterate the list. Otherwise we use the JavaScript filter function to filter the list and return it.

NOTE: This code could be simplified using regular expressions.

Lastly, we need the component:

import {Component} from ‘angular2/core’;
import {MovieFilterPipe} from ‘../common/movieFilter.pipe’

@Component({
    selector: ‘mh-movie-list’,
    templateUrl: ‘app/movies/movieListView.html’,
    styleUrls: [‘node_modules/bootstrap/dist/css/bootstrap.css’],
    pipes: [MovieFilterPipe]
})
export class MovieListComponent {

}

This is the component associated with the movie list view. The two critical steps for the pipe are:

1) Import the MovieFilterPipe.

2) Identify the pipe using the @Component decorator’s pipes array. This provides the list of all custom pipes available for the template.

For more information on Angular 1.x vs Angular 2, see “Angular 1.x to Angular 2 Quick Reference“.

For a sample application, see “Angular: 3 Flavors” which has the same application in Angular 1.x, Angular 1.x with TypeScript, and Angular 2.

Enjoy!

Next Page »

© 2016 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs

Featuring WPMU Bloglist Widget by YD WordPress Developer