Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

Archive for Angular

August 29, 2017

Filtering in Angular

Filed under: Angular @ 1:09 pm
Tags:

One common requirement is to filter a list of information based on user entered criteria. This post covers several techniques for filtering in Angular.

The content of this post is based on Angular version >= 2.x unless explicitly stated otherwise.

Filter Pipe

In AngularJS (Angular v1) we could easily filter information for display using a filter pipe. However, these often caused performance issues, so a built in filter pipe was not provided in Angular (v2+). We could, of course, build a custom pipe to perform our filtering. But that could have the same performance implications, so is not recommended.

From the Angular documentation:

Angular doesn’t offer such pipes because they perform poorly and prevent aggressive minification.

So what’s the alternative? Again from the Angular documentation:

The Angular team and many experienced Angular developers strongly recommend moving filtering and sorting logic into the component itself. The component can expose a filteredHeroes or sortedHeroes property and take control over when and how often to execute the supporting logic. Any capabilities that you would have put in a pipe and shared across the app can be written in a filtering/sorting service and injected into the component.

Filtering in the Component Code

The key to filtering in code is to provide a property for the filtered list and bind to that property. And to ensure that the filtering is performed every time the user changes the filter criteria, create a setter for the filter criteria property.

Let’s walk through some sample code:

import { Component, OnInit } from '@angular/core';

import { IProduct } from './product';
import { ProductService } from './product.service';

@Component({
    templateUrl: './product-list.component.html',
    styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {
    pageTitle: string = 'Product List';
    errorMessage: string;

    filteredProducts: IProduct[];
    products: IProduct[] = [];
    
    _listFilter: string;
    get listFilter(): string {
        return this._listFilter;
    }
    set listFilter(value: string) {
        this._listFilter = value;
        this.filteredProducts = this.listFilter ? this.performFilter(this.listFilter) : this.products;
    }

    constructor(private _productService: ProductService) {

    }

    performFilter(filterBy: string): IProduct[] {
        filterBy = filterBy.toLocaleLowerCase();
        return this.products.filter((product: IProduct) =>
              product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
    }

    ngOnInit(): void {
        this._productService.getProducts()
                .subscribe(products => {
                    this.products = products;
                    this.filteredProducts = this.products;
                },
                    error => this.errorMessage = <any>error);
    }
}

In addition to a products property that retains the complete list of products, we also have a filteredProducts property. In the HTML, we bind the displayed table to the filteredProducts property so only the filtered products are displayed in the list.

The listFilter property uses a getter and setter. A getter and setter provide a way to work with a property as a property, but still execute code when the property is retrieved (getter) or when the property is set (setter). In this example, we use the _listFilter property to hold the filter criteria value. We simply return that value in the getter. In the setter, we set the _listFilter property to the value passed into the setter and then perform the filter.

The x ? y : z syntax is a JavaScript conditional operator. It evaluates x and if x is true, it executes y. If x is false, it executes z. You can find out more about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator. In this specific example, the code is checking the listFilter property. If the property has a value, it calls the performFilter method. If the listFilter property has no value (meaning the user did not define filter criteria), then the filteredProducts property is set to the full list of products by assigning it to the products property.

In the HTML, we bind an input element to the listFilter property. As the user changes the filter criteria value, the setter is called and the filtering is re-executed.

We have a data service (ProductService) which retrieves the data. We inject that service into the constructor as we do any Angular service.

The performFilter method is where the filtering actually takes place.

The first line of this method converts the filterBy argument to lower case. When comparing strings, converting to lower case ensures that the matching is case insensitive.

The second line is using the JavaScript filter function (you can find our more about that here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

We want to filter the full list of products, so we call the filter function on this.products, which is the array to filter. The filter processes each element in the array and compares it using the provided arrow function. If the arrow function returns true, the item is included in the filtered list. If the arrow function returns false, the item is not included in the filtered list.

Notice, however, that we don’t have a return statement here in our arrow function!

(product: IProduct) => product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1


That’s because a one-line arrow function implicitly returns the function’s value. If the arrow function was multiple lines, then we would need both curly braces AND a return statement:

(product: IProduct) => {
    console.log(product.productName);
    return product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1;
}

Looking closer at the arrow function, we want to filter the list of products to only those products with a product name containing the user-defined filter text. So in the arrow function, we check the productName property of the product. We first convert the property value to lower case so that we are comparing both the property value and the filter string as lower case values.

We then use the indexOf function to locate the location of the filterBy text within the productName property. The indexOf function returns –1 if it does not find the defined text. We don’t really care where it finds the text, only that it does not return a –1.

You can download a complete example that uses this filter in the APM-Final folder of this github repo: https://github.com/DeborahK/Angular-GettingStarted

Or to see this filter built step-by-step in a video, check out my course: http://bit.ly/Angular-GettingStarted

Filtering on Multiple Criteria

Filtering on multiple criteria is just a matter of modifying the perform filter method. For example, say we want to filter based on either the product name or the product description. The performFilter code would then look like this:

    performFilter(filterBy: string): IProduct[] {
        filterBy = filterBy.toLocaleLowerCase();
        return this.products.filter((product: IProduct) =>
              product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1 || 
              product.description.toLocaleLowerCase().indexOf(filterBy) !== -1);
    }

We’ve simply added an OR conditional operator. So if the text is found in the productName or in the description, the item will be included in the filtered list.

Filtering on Criteria Matching any Object Properties

There may be times that you want to generically filter based on the value of any of an object’s properties. For example, find a particular string in *any* property of a product. In this case, the performFilter code would look something like this:

    performFilter(filterBy: string): IProduct[] {
        filterBy = filterBy.toLocaleLowerCase();
        return this.products.filter((product: IProduct) => 
            Object.keys(product).some(prop => {
                let value = product[prop];
                if (typeof value === "string") {
                    value = value.toLocaleLowerCase();
                } 
                return value.toString().indexOf(filterBy) !== -1;
            })    
        );
    }

This code uses Object.keys(product) to access each of the product object properties. It then uses the JavaScript some function (detailed here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) which tests whether at least one element in the array of properties passes the test defined by the arrow function. So as soon as the filter text is found in any property, it stops iterating through the remaining properties and simply returns true to include the item in the filtered list.

In the some function’s arrow function, we first access the actual value of the property using product[prop]. In JavaScript, we can access the properties of an object as a set of key and value pairs. Unless we know for sure that all of our properties are strings, we’ll have to do some additional processing based on the type. So we’ll handle our property strings different from our numbers.

NOTE: This code was not tested with complex object graphs where a property of the object is itself another object. For that scenario, some additional code is required.

If the property value is a string, we convert it to lower case so that we can compare the lower case value to the lower case filter criteria. We then use the toString function to ensure the value is converted to a string before calling the indexOf function since indexOf only works on strings.

Filtering at the Server

If, however, you have hundreds or thousands of rows, downloading all of that data and filtering on the client may be just to inefficient. In that case, consider requesting the filter criteria first, then passing that criteria to your server, returning only the rows that match the criteria. Then you no longer need filtering on the client.

Enjoy!

August 10, 2017

Angular: Getting Started Course Update (for v4.3)

Filed under: Angular,Angular CLI @ 1:59 pm
Tags: ,

This post identifies the latest changes to the “Angular: Getting Started” Pluralsight course.

History

Angular 2 first appeared around June of 2015 as alpha.27. The first beta release of Angular 2 was December 12, 2015, a great time to start on an Angular 2 getting started course. The first release of the “Angular 2: Getting Started” course was on April 1st, 2016. The code examples for the course were valid through Angular beta.15. From that time until release, Angular underwent numerous changes … some, such as the new router and the introduction of Angular modules, were significant.

Angular 2.0.0 was released on September 14th, 2016, so that was a great time to update the “Angular 2: Getting Started” course. That update was released October 19, 2016 and completely replaced the entire course. The original course was deprecated and the update was given a new link in the Pluralsight library.

Angular 4.0 was released on March 23, 2017 and included many great compiler and performance improvements, but not many feature changes that affected this course. However, the Angular CLI was also released around this time and began to be a viable and very productive alternative for generating Angular code.

Angular 4.3 was released on July 14th, 2017 and introduced a new HttpClient module. This seemed like a great time then to update this course *and* include content on using the Angular CLI. This update was provided as a patch to the existing course and was published to the Pluralsight library on August 10, 2017.

If you have already watched the course and want to minimize which modules to re-watch, I’d suggest modules 2, 6, 9 and 13. That would provide a look at the key changes.

The changes to this course include:

Module 1: Introduction

  • Changed all references from “Angular 2” to just “Angular”
  • Changed the course introduction to include the new CLI module (module 13)

Module 2: First Things First

  • Changed all references from “Angular 2” to just “Angular”
  • Updated the screen shot for the latest npm version
  • Updated the discussion of the Angular CLI
  • Updated the discussion of the sample starter files
  • Updated the discussion of the folder structure to match that generated by the Angular CLI
  • Added information on the package.json file and how it works
  • Updated the demo of the installation process
  • Updated the demo of running the application
  • Removed the clip that covered module loading with SystemJS
  • Split one of the clips into two to keep the same number of clips (required by the Pluralsight patching process).

Module 3: Introduction to Components

  • Changed all references from “Angular 2” to just “Angular”
  • Changed the selector in all examples to match that generated by the CLI
  • Updated the demos to reflect the new folder structure and CLI generated code
  • Changed the discussion of the bootstrap process to focus on hosting the app and creating the root App module
  • Added more information on using the developer tools and debugging using the source maps

Module 4: Templates, Interpolation, and Directives

  • Changed all references from “Angular 2” to just “Angular”
  • Changed the selector in all examples to match that generated by the CLI
  • Changed all templateUrl paths to relative paths
  • Removed the “Loading App” message from the demos since the CLI does not generate it
  • Updated all demos that include display of the application folder structure
  • Added a demo of the quick fix feature of VS Code to automatically add import statements

Module 5: Data Binding & Pipes

  • Changed all references from “Angular 2” to just “Angular”
  • Changed all templateUrl paths to relative paths
  • Updated the demos to reflect the new folder structure

Module 6: More on Components

  • Changed all references from “Angular 2” to just “Angular” 
  • Changed all templateUrl paths to relative paths
  • Updated the demos to reflect the new folder structure
  • Removed the demo of hiding the .js and .map files since they are no longer generated in the same folder as the .ts files
  • Replaced the custom pipe example with a new example that better fits with best practices
  • Removed the clip on relative paths and module Id. When using Webpack, relative paths are available without the need to add a module Id
  • Added a clip on how to filter the products using code in the class. This clip introduces property getters and setters

Module 7: Building Nested Components

  • Changed all references from “Angular 2” to just “Angular”
  • Changed all templateUrl paths to relative paths
  • Updated the demos to reflect the new folder structure
  • Changed the selector for the star component from ‘ai-star’ to ‘pm-star’ to ensure the app will pass linting rules.
  • Changed the order of the steps in the demo of the @Output decorator to improve the flow of the demo.

Module 8: Services and Dependency Injection

  • Changed all references from “Angular 2” to just “Angular”
  • Changed all templateUrl paths to relative paths
  • Updated the demos to reflect the new folder structure

Module 9: Retrieving Data Using Http

  • Changed all references from “Angular 2” to just “Angular”
  • Updated the demos to reflect the new folder structure
  • Updated the demo to illustrate the asynchronous nature of the data retrieval
  • Updated Http to HttpClient and HttpModule to HttpClientModule as per Angular 4.3

Module 10: Navigation and Routing Basics

  • Changed all references from “Angular 2” to just “Angular”
  • Added a new Clip 2 in between the existing clips 1 and 2 that uses the CLI to create the Product Detail component, discusses how to handle undefined values, and adds the Welcome component (These new components are required to demonstrate routing)
  • Changed the "product/:id" route to "products/:id" to better match with best practices
  • Updated all slides and demos that include display of the application folder structure, show relative paths, show changed selectors, reflect prior code changes, or could use the VS Code quick fix

Module 11: Navigation and Routing Additional Techniques

  • Changed all references from “Angular 2” to just “Angular”
  • Changed the "product/:id" route to "products/:id" to better match with best practices
  • Updated all slides and demos that include display of the application folder structure, show relative paths, show changed selectors, reflect prior code changes, or could use the VS Code quick fix
  • Modified the demo to use the CLI to create the guard service
  • Added a slide with a reference to the "Angular Routing" course

Module 12: Angular Modules

  • Changed all references from “Angular 2” to just “Angular”
  • Updated all slides and demos that include display of the application folder structure, show relative paths, show changed selectors, reflect prior code changes, or could use the VS Code quick fix
  • Changed the creation of the feature and shared modules to use the Angular CLI
  • Enhanced the discussion of ordering modules in the imports array and its effects on route configuration

Module 13: Building, Testing, and Deploying with the CLI

  • New module completely replacing the original module and now covers the Angular CLI
  • (Was “Angular 2 Setup Revisited”, which went through the SystemJS files)

Module 14: Final Words

  • Changed all references from “Angular 2” to just “Angular”
  • Updated all slides that include display of the application folder structure, show relative paths, show changed selectors, reflect prior code changes, or could use the VS Code quick fix
  • Added a slide on the CLI in the summary
  • “Learning More” now includes more Angular courses from the Pluralsight library

Plus I brought in a professional to clean up the audio for the entire course!

    Enjoy!

    June 16, 2017

    Angular Learning Path

    Filed under: Angular @ 4:06 pm

    The content of this post is based on Angular version >= 2.x unless explicitly stated otherwise.

    Are you looking for a path for learning Angular? Try these courses on Pluralsight:

    Angular: Getting Started (5h 26 m)

    This course gets you started with the basics of Angular including building components, services, and Angular modules.

    Angular CLI (2h 26 m)

    In this course, you will learn how to create, generate, lint, debug, test, build, and serve high quality apps that follow the Angular Style Guide using the Angular CLI.

    Angular Reactive Forms (3h 54 m)

    This course details how to build Reactive forms, validate user-entered data, and perform CRUD (Create, Read, Update, and Delete) operations using HTTP.

    Angular Routing (4h 46 m)

    In this course, you’ll learn how to define multiple routes, pass data to routes, guard your routes, preload data for your views, lazy load routes for better performance and more.

    Angular Fundamentals (9 h 59 m)

    This course expands on the basics and covers more intermediate information on every key aspect of Angular, including component communication, creating directives, testing, and deployment.

    Enjoy!

    June 15, 2017

    Property ‘x’ is private and only accessible within class ‘MyComponent’

    Filed under: Angular @ 6:13 pm

     

    The content of this post is based on Angular version >= 2.x unless explicitly stated otherwise.

    As with any application framework, there are those issues that trip up many developers. Some of these are due to changes to the framework over time, others are just unexpected results from seemingly correct code. I’ve tried to capture some of the more common issues and their solutions and here is one of them.

    Property ‘x’ is private and only accessible within class ‘MyComponent’.

    This issue began with Angular 4 and the release of the CLI. The Angular CLI enables the Ahead of Time (AOT) compiler when you use the `ng build –prod` option. The Ahead of Time compiler compiles things a bit differently, hence the reason this issue only appears with AOT.

    Original sample code:

    import { Component } from '@angular/core';
    
    @Component({
        selector: 'mh-root',
        template: `
            {{pageTitle}}
            <router-outlet></router-outlet>
         `
    })
    export class AppComponent {
        private pageTitle: string = 'InStep Movie Hunter';
    }

    Error: Property ‘pageTitle’ is private and only accessible within class ‘AppComponent’.

    Issue: With AOT, private properties and methods in the class are only accessible within the class. To access the property or method in the template, the property or method must be declared public.

    Updated sample code:

    import { Component } from '@angular/core';
    
    @Component({
        selector: 'mh-root',
        template: `
            {{pageTitle}}
            <router-outlet></router-outlet>
         `
    })
    export class AppComponent {
        public pageTitle: string = 'InStep Movie Hunter';
    }

    For more information: https://github.com/angular/angular-cli/issues/5623

    Enjoy!

    June 2, 2017

    Passing Data to and Raising an Event from a Nested Component

    Filed under: Angular @ 1:33 pm
    Tags:

     

    The content of this post is based on Angular version >= 2.x unless explicitly stated otherwise.

    Let’s look at how to pass data to a nested component and raise an event from a nested component. But first, let’s define what a nested component is.

    A nested component is an Angular component that provides some piece of the user interface and is embedded within the template of another Angular component. As shown in the image below, we created a component that displays a number as a set of stars. We can then nest this component in any other component that wants to use it, reusing it as needed. In this example, we nested it within the Product List component.

    The code required to nest the component is shown below.

    Thumbnail

    In this example, the Star component is the component that will be used as a nested component. Notice it’s selector (ai-star). The Star component is nested in the Product List component’s template by using its selector as a directive.  The Product List component is then referred to as the parent component.

    If we want to pass data from the parent component to the nested component, we define an @Input decorator on a property of the nested component. In this example, we define a rating property with the @Input decorator. This will be the rating value that we want to display as stars.

    Then when we nest the component using the <ai-star> directive, we use data binding to bind the property decorated with @Input to a value from the parent component. This passes the data into the nested component.

    In this example, we use property binding to bind the rating property to the product’s starRating property defined within the Product List component. That value then comes through to the @Input rating property in the start.component.ts.

    But what if we want to raise an event from the nested component back to the parent? Let’s look at the flow for that:

    Thumbnail

    (1) The user clicks on the star component in the html. We use event binding to bind to a method in the Star Component.
    (2) The specified method (onClick) is executed.
    (3) The onClick method uses the emit method of an EventEmitter ((4) defined with an @Output decorator) to emit the desired event and passes ‘clicked!’ as the event parameter
    (4) Each event to be emitted from the nested component must be defined with an @Output decorator. The event is created using the new keyword. The type of value passed to the event is defined as a generic parameter (<string> in this example)
    (5) The parent component (Product List component in this example), uses event binding to bind to the event defined with the @Output decorator (4).
    (6) When the event is emitted from the nested component (3), the onNotify method of the Product List component is called, passing in the event parameters (‘clicked!’ in this case)
    (7) The onNotify method of the Product List component is executed and any code within that method is executed.

    Enjoy!

    May 5, 2017

    Build a Simple Angular Service to Share Data

    Filed under: Angular @ 2:20 pm
    Tags: ,

    The content of this post is based on Angular version >= 2.x unless explicitly stated otherwise.

    I’ve seen some complex code on Stackoverflow and elsewhere recently where the developer was using Subject and Behavior Subject as part of an Observable solution to simply share data between unrelated components with Angular. In some cases, the Observable approach may be necessary. But in many cases, the solution can be much simpler without Observables.

    For example, you may want to retrieve some user preferences and retain them for use by any component in the application. Or you may want to store some user-entered values, such as the selected currency, throughout the application.

    Just build a simple service to service up that data to any component that injects the service.

    image

    The example in this post defines two unrelated components, Component A and Component B, that want to share data. But there could be any number of components that share this data.

    First, we create a service that holds the data. Since a service is a singleton, all of the components that inject this service can share the data from this service:

    import { Injectable } from '@angular/core';
    
    @Injectable() 
    export class DataService {
      serviceData: string; 
    }

    This particular service simply provides for sharing the service data. This data could be of any type, including an object. And there could be more code here, such as code to retrieve default values for this serviceData from a back-end server.

    Each component then injects this service and uses its value:

    import {Component} from '@angular/core'
    
    import { DataService } from './data.service';
    
    @Component({ 
     template: ` 
      <div> 
        <h2>Data from A: {{ data }} </h2> 
        <input [(ngModel)] = data /> 
        <br><br> 
        <a [routerLink]="['/b']">Go to B</a> 
      </div> 
      `, 
    }) 
    export class A {
    
      get data():string { 
        return this.dataService.serviceData; 
      } 
      set data(value: string) { 
        this.dataService.serviceData = value; 
      } 
      
      constructor(public dataService: DataService) { } 
    }

    There are two key bits of code here:

    • The dataService is injected into the constructor.
    • The property is defined as a getter/setter so that the current value is get/set from the service.

    The second component is similar:

    import {Component} from '@angular/core'
    
    import { DataService } from './data.service';
    
    @Component({ 
     template: ` 
      <div> 
        <h2>Data from B: {{ data }} </h2> 
        <input [(ngModel)] = 'data' /> 
        <br><br> 
        <a [routerLink]="['/a']">Go to A</a> 
      </div> 
      `, 
    }) 
    export class B { 
      get data():string { 
        return this.dataService.serviceData; 
      } 
      set data(value: string) { 
        this.dataService.serviceData = value; 
      } 
     
     constructor(public dataService: DataService) { } 
    }

    And for completeness, here are the app module and app component: (This was written using a Plunker, so the app module and app component are in the same file.)

    import {Component, NgModule, VERSION} from '@angular/core'; 
    import {BrowserModule} from '@angular/platform-browser'; 
    import { RouterModule } from '@angular/router'; 
    import { FormsModule } from '@angular/forms';
    
    import { A } from './a.component'; 
    import { B } from './b.component';
    
    import { DataService } from './data.service';
    
    @Component({ 
      selector: 'my-app', 
      template: ` 
      <div> 
        <h2>Hello {{name}}</h2> 
        <router-outlet></router-outlet> 
      </div> 
      `, 
    }) 
    export class App { 
      name:string; 
      constructor() { 
        this.name = `Angular! v${VERSION.full}` 
      } 
    }
    
    @NgModule({ 
      imports: [ 
        BrowserModule, 
        FormsModule, 
        RouterModule.forRoot([ 
          { path: '', redirectTo: 'a', pathMatch: 'full'}, 
          { path: 'a', component: A }, 
          { path: 'b', component: B } 
        ]) 
      ], 
      declarations: [ 
        App, 
        A, 
        B 
      ], 
      providers: [ DataService ], 
      bootstrap: [ App ] 
    }) 
    export class AppModule {}

    In this particular case, since both components are routed to each other, this data could instead be passed to the components as a required, optional, or query routing parameter. But this solution works in cases where the components want to share data without necessarily passing it as part of routing.

    You can find the plunker here: https://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview

    For more information on building services, check out my Pluralsight course: Angular 2: Getting Started

    Enjoy!

    March 31, 2017

    “Angular Routing” Problem Solver

    This blog post supports the sample code for the “Angular Routing” course on Pluralsight, identifying common issues along with their solutions.

    The content of this post is based on Angular version >= 2.x unless explicitly stated otherwise.

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

    • APM–Start: The starter files. Use this as a starting point to code along with the course. Updated to Angular v4.
    • APM–Final: The completed files. This code matches with the demos presented in the course. Updated to Angular v4.

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

    Here’s What Developers are Saying About the “Angular 2: Getting Started” Course

    Filed under: Angular @ 2:05 pm
    Tags: , ,

    I had well over 1000 comments in the “Angular 2: Getting Started” discussion section (and another 1200+ for the Angular beta version of the course) before livefyre shut it down. Here is a sample of some of the great comments left by course viewers:

    What Developers Are Saying

    I always thought Angular was hard, but your way of explaining it makes it easy to understand and fun.

    Extreme quality tutorial as always!

    Many thanks for this really good introduction to Angular 2. It is so refreshing to come across a course that I can understand.

    I just completed the course.  It has been one of the best training courses I’ve viewed.  I came into this course not liking the idea of a paradigm shift from Angular 1 to 2, but after viewing this course, I like 2 much better than 1.

    Maybe the best tutorial I’ve seen of all programming tutorials. Love the way how you start and finish every module with checklists and revisitings. Angular 2 seems so easy to learn with you.

    I have been using Angular 1.5 for over a year in a pure .net environment.  I was confused by the many Angular2 training options that did not fully explain Node and NPM.  Your course has opened my eyes.  Thank you for your explanations.  Great  job!  And great course!!

    Thank you for the awesome course, Deborah! I really enjoyed it, learned a lot and chuckled quite a few times – especially at the "ng for nnngular" and you going "Yay!" every time something works – mainly because I do the exact same while I’m coding! :)  Really informative, easy to follow and information rich course – thank you!

    Your course is one of the best, if not the best in Pluralsight and it has made learning Angular 2 fun and a lot less stressful.

    Finished up the course yesterday and I must say it was a great learning experience.  Your organization and content is very well thought out (I’m sure I’ll revisit the checklists at the end of each module many times.)  Your delivery and pace were also excellent.

    If you would be my teacher in the college ,then i would have given 100% attendance. Haha 😛 . You explain everything in a very good manner :).

    This course is awesome. Impressive clarity.

    Such a great course! Really made me understand the basic patterns of Angular 2, which was all very confusing for me before taking the course. Thank you!

    Thank you for the SUPERP material on Angular 2. I have been following along your course and able to build my project.

    Excellent method of teaching. Organized, lucid, coherent, structured.

    Great course! How can anyone watch it just once?

    Thanks for very useful course, I have completed the course and start doing my own angular 2 project for web application.

    Just wanted to tell you how much I enjoyed your course, it’s given me a good foundation for angular2.

    i really enjoy this course  it is great for beginners.

    Thanks for a wonderful angular2 getting started course! It’s really helpful.

    Thanks for a wonderful insight into Angular 2.

    Outstanding. Teaching is an art which you have it in you. Thank you so much.

    Thanks for the awesome course. I really enjoyed it.

    your course is one of my favorite in the pluralsight. you are doing a great job!

    This is a wonderful course, thank you.

    thank you so much for your wonderful tutorial . I really love your teaching method . make them easy to understand.

    Thank you for this great course. It is so detail and easy to follow.

    Thank you for a great course. I loved the little bits of personality that you dropped in randomly. It makes a big difference for me.

    A very good and detailed course; in-particular the recap and the end of each module and the really good slides. I am keeping those as reference diagrams on my wall.

    Awesome course, Deborah is so clear and organized that even an idiot like me can understand.

    This is a very exciting tutorial. I have learned so easy the Angular 2 base knowledge. Thank you very much.

    Great course Deborah. Its become my reference point for all things Angular2.

    Very helpful and structured tutorials! I wish I found out about these earlier.

    Thanks Deborah for an excellent tour of Angular 2. Course content/speed is just too good. 5 stars from me.

    Thank you for such a wonderful course. I was able to build a small app with your course guidance.

    Great course, enjoying it very much, and particularly appreciate the way you present the material in a way where you deliberately encounter the same issues other "newbies" to Angular would encounter, and present the very logical resolutions to them. In that way I’m coming the appreciate the plumbing required so much more quickly than via some other resources I’ve been using.

    Excellent content, your course coupled with John Papa’s course really helped me  get up and running with Angular 2. You are very thorough in your coverage, keep up the good work…

    Fantastic, fantastic job — clear, comprehensive throughout, with clearly explained and shown examples.

    Thanks Deborah for this wonderful and easily understandable course.Your course is designed and explained in such a wonderful way that after this course i do not require to search for another.Great job…….

    You are an excellent tutor. I am loving the course and in spite of having no knowledge about angular JS version 1 i am getting a hold of angular 2. Thanks a ton.

    Thank you for this fantastic course on Angular 2. Having never programmed in Angular 2 before, I found this course to be very helpful on the basic concepts of Angular 2. The amount of of time and detail spent on each topic contributed greatly to my understanding of programming in Angular 2. I very much look forward to your next course on Angular 2 – Angular 2: Reactive Forms.

    Thanks Deborah for another excellent course.  I finished it without any problems.  Keep them coming 🙂

    Super course I thoroughly enjoyed and went through it twice.

    You are the most amazing tutor because:

    • You make everything so simple to understand.
    • Rather bluntly developing app and saying "What to do?", you take the time to say "Why to do it?".
    • You gave clear insight by going to every minute details. It is important to understand the basics.
    • You repeat and remind the concepts to make it familiar. It makes remembering them easy.
    • After completing this course, I now understand Architecture of Angular Application. So, I can develop manageable angular applications.

    What Developers Are Requesting

    Could you add additional lesson for paging service in future, in addition to firebase database with angular 2?

    It would be great if you can throw some light on how to make use of font-awesome css & icons in the same project.

    Kindly share the course or session on JIT & AOT

    using npm behind a corporate proxy is a major hassle.  Is this addressed in a class somewhere?

    I would like to have lectures on Security ( Angular2 application in banking domain ) and Unit testing.

    A course on a web framework is incomplete IMO without coverage on working with forms data as intended by that framework.
    Basic CRUD, even if with a mocked-up in-memory storage. [Covered in “Angular 2: Reactive Forms”]

    Up next, NodeJS, React or React Native maybe?

    Record an Ionic 2 course please!

    It would be nice to see an advanced version for it. Something with Animations, Authorization, automatic build, testing. Things like that. [Covered in “Angular 2 Fundamentals”]

    In your next course can you pl address some advanced topics like Forms, Security, Angular Material2. [Forms are covered in “Angular 2: Reactive Forms”]

    January 9, 2017

    Angular Route Ordering

    Filed under: Angular @ 10:02 am
    Tags: , ,

    The content of this post is based on Angular version >= 2.x unless explicitly stated otherwise.

    In Angular, the ordering of the routes in the route configuration matters. And when using feature and routing modules, it is easy to get the routes out of their needed sequence.

    Basic Configuration

    The following is an example Angular route configuration commonly defined in an app.module.ts file:

    RouterModule.forRoot([

      { path: ‘welcome’, component: WelcomeComponent } ,

      { path: ‘products’, component: ProductListComponent },

      { path: ‘product/:id’, component: ProductDetailComponent }

      { path: ”, redirectTo: ‘welcome’, pathMatch: ‘full’},

      { path: ‘**’, redirectTo: ‘welcome’, pathMatch: ‘full’ }

    ])

    The welcome route displays the template for the Welcome Component. (www.mysite.com/welcome)

    The products route displays the template for the Product List Component. (www.mysite.com/products)

    The product/:id route is a parameterized route. It displays the template for the Product Detail Component with the product defined by the id parameter. (www.mysite.com/product/42)

    The empty path specifies a default route. This is the route that is matched when no path is specified. In this example, the default route redirects to the welcome route. (www.mysite.com)

    The ** defines a wildcard path. This is the route that is matched when no other prior route is matched. It is often used for displaying a 404 (not found) page. But in this example, it redirects to the welcome route. (www.mysite.com/hello)

    These routes are processed from top to bottom and the first match wins.

    If we moved the wildcard path up to the top of the list like this:

    RouterModule.forRoot([

      { path: ‘**’, redirectTo: ‘welcome’, pathMatch: ‘full’ }

      { path: ‘welcome’, component: WelcomeComponent } ,

      { path: ‘products’, component: ProductListComponent },

      { path: ‘product/:id’, component: ProductDetailComponent }

      { path: ”, redirectTo: ‘welcome’, pathMatch: ‘full’}

    ])

    None of the other routes would ever be matched. The wildcard would always be picked first. So take care on the ordering of the routes in your route configurations.

    Feature Modules

    As an application gets larger, it is best to break out the features into their own feature modules. This makes the code easier to work with and maintain.

    In the above example, we can refactor the product features out of the app.module.ts and add them to their own product.module.ts (ProductModule):

    RouterModule.forChild([
        { path: ‘products’, component: ProductListComponent },
        { path: ‘product/:id’, component: ProductDetailComponent },
    ])

    The resulting app.module.ts routes then look like this:

    RouterModule.forRoot([

      { path: ‘welcome’, component: WelcomeComponent },

      { path: ”, redirectTo: ‘welcome’, pathMatch: ‘full’ },

      { path: ‘**’, redirectTo: ‘welcome’, pathMatch: ‘full’ }

    ]),

    ProductModule

    But wait! Isn’t our wildcard route now ahead of our product routes? How will our product routes ever be matched?

    As it turns out, Angular handles this differently than we may expect. When the RouterModule.forRoute or RouterModule.forChild is used directly, it is processed last. All of the Angular modules (such as ProductModule) are processed first. So even though we define the wildcard route above ProductModule in this example, the routes defined in the RouterModule.forRoot() are moved to the end and processed last. So all of our routes still work as expected.

    Routing Modules

    In some cases, we may want to remove the routes from the app.module.ts and move them to their own module, such as app-routing.module.ts (AppRoutingModule):

    RouterModule.forRoot([

    { path: ‘welcome’, component: WelcomeComponent },

    { path: ”, redirectTo: ‘welcome’, pathMatch: ‘full’},

    { path: ‘**’, redirectTo: ‘welcome’, pathMatch: ‘full’ }

    ])

    If we then simply replace the routes in app.module.ts with the routing module like this:

    AppRoutingModule,

    ProductModule

    Our product routes will stop working. Now that all of our routes are in modules, they are processed in their defined order. So the wildcard path in the AppRoutingModule will come *before* any of the routes defined in the ProductModule.

    The app.module.ts modules must instead be defined in the appropriate order:

    ProductModule,

    AppRoutingModule

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

    For a code example, check out my github repo.

    Enjoy!

    October 18, 2016

    Angular 2: Getting Started Course Update

    This post identifies the changes to the “Angular 2: Getting Started” Pluralsight course from its first release on April 1st, 2016 to its update October 18th, 2016.

    Angular 2 first appeared around June of 2015 as alpha.27. The first beta release of Angular 2 was December 12, 2015, a great time to start on an Angular 2 getting started course. The first release of the “Angular 2: Getting Started” course was on April 1st, 2016. The code examples for the course were valid through Angular beta.15. From that time until release, Angular underwent numerous changes … some, such as the new router and the introduction of Angular modules, were significant.

    Angular 2.0.0 was released on September 14th, 2016, so that was a great time to update the “Angular 2: Getting Started” course. The changes made to each module of the course are outlined below.

    If you have already watched the course and want to minimize which modules to re-watch, I’d suggest modules 2, 10, 11, and 12. That would provide the basics on Angular modules (NgModule) and the new router.

    Module 1: Introduction

    • Introduced Angular modules.
    • Updated Course Outline.

    Module 2: First Things First

    • Demoed how to get a more current version of npm.
    • Revised setup steps including the application’s root Angular module.
    • Updated discussion of AngularCli.
    • Updated demos for setting up Angular 2.
    • Enhanced discussion in “About Modules” regarding the difference between ES modules and Angular modules.

    Module 3: Introduction to Components

    • Updated demos for new import statements (import from @angular/… instead of angular2/…)
    • A first cut of the app.component.ts is now included as part of the starter files. This changes some of the initial steps when building the app.component.ts file.
    • Added a callout to point out the use of the back tick (not quotes) for defining the inline template.
    • Bootstrapping process now includes the application’s root Angular module.
    • Additional checklist for resolving issues when coding along.

    Module 4: Templates, Interpolation, and Directives

    • Updated demos for new import statements (import from @angular/… instead of angular2/…).
    • Added steps to update the application’s root Angular module (AppModule).
    • Added information on how an Angular module defines the boundary or context within which the component resolves its directives and dependencies.
    • Added a demonstration of a common Angular error and how to fix it.
    • Updated the ngFor syntax to match the released syntax using the let keyword instead of #.

    Module 5: Data Binding & Pipes

    • Updated demos for new import statements (import from @angular/… instead of angular2/…).
    • Added information on adding FormsModule to an Angular module so the template can use ngModel for two-way binding.

    Module 6: More on Components

    • Updated demos for new import statements (import from @angular/… instead of angular2/…).
    • Updated the code for the pipe transform to match the new transform signature.
    • Added a step to add the custom pipe to an Angular module.
    • Added a clip on using component-relative paths by setting module Ids.

    Module 7: Building Nested Components

    • Updated demos for new import statements (import from @angular/… instead of angular2/…).
    • Added a step to add the nested component to an Angular module.

    Module 8: Services and Dependency Injection

    • Updated demos for new import statements (import from @angular/… instead of angular2/…).
    • Mentioned how service can be registered in an Angular module.

    Module 9: Retrieving Data Using Http

    • Updated demos for new import statements (import from @angular/… instead of angular2/…).
    • Enhanced discussion of Observables.
    • Enhanced the comparison between Promises and Observables.
    • Removed the setup clip since these setup steps are no longer valid.
    • Added a step to add Http to an Angular module.
    • Separated out the exception handling to its own clip.

    Module 10: Navigation and Routing Basics

    • Divided this course module into two modules: 10 and 11.
    • Major modifications throughout to change to the current router.
    • Expanded on the details for how routing works.
    • Enhanced the discussion of Html 5 vs hash style routes.
    • Updated demos for new import statements (import from @angular/… instead of angular2/…).
    • Added steps to add the remaining components to an Angular module.

    Module 11: Navigation and Routing Additional Techniques

    • This new module is the second half of the prior module.
    • Major modifications throughout to change to the current router.
    • Updated demos for new import statements (import from @angular/… instead of angular2/…).
    • Added a clip on route guards.

    Module 12: Angular Modules

    • This new module is all about Angular modules. It covers:
      • The definition and purpose of an Angular module.
      • Understanding the Angular module metadata and its many rules.
      • Refactoring the sample application and creating a feature module.
      • Minimizing repetition by creating a shared module.
      • Reexamining the root application module (AppModule).
      • A look at building separate routing modules.
      • And summarizing options for your Angular module architecture.

    Module 13: Angular 2 Setup Revisited

    • Updated the demos to the Angular 2 release setup files.
    • Added discussion of the systemjs.config.js file.
    • Added discussion of the bootstrapping process differences for the Just in Time (JiT) compiler vs the Ahead of Time (AoT) compiler.
    • Added discussion of the Angular CLI.

    Module 14: Final Words

    • Minor wording changes.

    Enjoy!

    Next Page »

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