Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

Archive for Angular

November 8, 2018

Angular: Getting Started Course Update (for v7)

Filed under: Angular,Angular CLI @ 2:58 pm

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: 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: 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 v4.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 v4.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.

Angular v6 was released on May 3, 2018. There was very little changed in Angular, but RxJS changed significantly as did Bootstrap. So time for another update to this course. This update was provided as a patch to the existing course and was published to the Pluralsight library on July 11, 2018.

Angular v7 was released on October 18, 2018. There was very little changed in Angular, but the CLI was enhanced and includes user prompts.

The key changes include:

  • Update to Angular v7.
  • Update to the Angular CLI to include user prompts.

The detailed changes to this course include:

Module 2: First Things First

  • Replaced screens showing the package.json to show the v7 packages. (Clip 6, 7)

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

  • Replaced screens showing the package.json to show the v7 packages. (Clip 2, 3, 4)
  • Modified the demo of the CLI to include the user prompts. (Clip 3)

Enjoy!

November 6, 2018

Angular Reactive Forms Course Update (for v7)

Filed under: Angular @ 11:18 pm

This post identifies the latest changes to the “Angular Reactive Forms” Pluralsight course.

History

The first release of the “Angular Reactive Forms” course was in January of 2017. It supported Angular 2.0 and did not use the Angular CLI, which was not yet released at that time.

On November 6, 2018, this course was updated to Angular v7.

The key changes include:

  • Update to Angular v7.
  • Update to the Angular CLI.
  • Update to Bootstrap v4 and Font Awesome (since Bootstrap no longer provides icons).
  • Update to the HttpClient module, which was new in Angular v4.3.
  • Update to RxJS v6, which includes new import statements and pipeable operators.
  • Modified to use the new providedIn property of the Injectable decorator to register services.

The detailed changes to this course include:

Module 1: Introduction

  • Changed from “Angular 2” to just “Angular” on the slides and in the narration. (Clip 1, 3, 4)
  • Changed from “Angular 1” to “AngularJS” on the slides. (Clip 2)
  • Updated the screenshot of the GitHub repository. (Clip 3)
  • Upgraded from Bootstrap 3 to Bootstrap 4 and Font Awesome which changed the visual appearance of the pages. (Clip 4)
  • Added delete functionality for the tags. (Clip 4)

Module 2:Template-driven vs. Reactive Forms

  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 1)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages. (Clip 2)
  • Added callouts to clarify state. (Clip 2)
  • Added examples to clarify the form building blocks. (Clip 2)
  • Added callouts to clarify the directives. (Clip 3)
  • Upgraded to Bootstrap 4 which changed the styles in the HTML, specifically how validation error styles are handled. (Clip 4)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages and style classes in the Html. (Clip 5, 6, 7, 8)
  • Split clip 5 into 2 clips for a more reasonable clip length.
  • Added a demo slide. (Clip 6, 7)
  • Added information regarding the new Bootstrap 4 is-invalid and invalid-feedback style classes. (Clip 6)
  • Changed SmartArt to Pluralsight standard slide design. (Clip 8)

Module 3: Building a Reactive Form

  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 1, 4)
  • Re-recorded the demos to match the current sample code. (Clip 3, 4, 6, 7, 8)
  • Minor updates to the slides for Bootstrap 4 styles. (Clip 5)
  • Split clip 5 into 2 clips for a more reasonable clip length.
  • Added a demo slide. (Clip 6)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages and style classes in the Html. (Clip 6, 7, 8)
  • Minor update to the slides to remove style classes. (Clip 9)

Module 4: Validation

  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 1)
  • Re-recorded the demos to match the current sample code. (Clip 2, 3, 4, 5, 6, 7)
  • Changed the email pattern validator to the new email validator. (Clip 2, 6)
  • Updated the screen shot in the slides due to changes in Bootstrap 4. (Clip 3, 4, 6)
  • Reformatted the code in the slides to make it easier to read. (Clip 4, 5, 7)
  • Changed the default value of the rating from a string to null since it is a numeric value. (Clip 4)
  • In the demo, included a look at the built in min and max validators. (Clip 4)

Module 5: Reacting to Changes

  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 1)
  • Modified the slide to remove the SmartArt and add callouts. (Clip 2)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages. (Clip 2, 3)
  • Re-recorded the demos to match the current sample code. (Clip 2, 3, 4, 5)
  • Changed SmartArt slide to Pluralsight standard slide design. (Clip 3)
  • Changed the email pattern validator to the new email validator. (Clip 4)
  • Added a detailed callout to show the mapping of the errors collection to the error messages structure. (Clip 4)
  • Updated the demo to use the RxJS version 6 import statement. (Clip 5)
  • Updated the demo to use the RxJS pipeable operator. (Clip 5)
  • Updated the code in the slides due to changes in RxJS and Bootstrap 4. (Clip 6)

Module 6: Dynamically Duplicate Input Elements

  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 1)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages. (Clip 1)
  • Updated the screen shot in the slides due to changes in Bootstrap 4. (Clip 3)
  • Re-recorded the demos to match the current sample code. (Clip 3, 4, 5, 6, 7, 8. 9)

Module 7: Reactive Form in Context

  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 1, 2)
  • Updated the screenshot of the GitHub repository. (Clip 2)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages. (Clip 2, 5)
  • Re-recorded the demos to match the current sample code. (Clip 2, 4, 5, 6. 7, 8)
  • Removed the Product List Filter pipe component from the slides because using a pipe to build a filter is no longer recommended. (Clip 3)
  • Changed HttpModule to HttpClientModule in the slides as this was changed in Angular v4.3. (Clip 3)
  • Removed the services from the ProductModule in the slides since services are no longer defined in a module. (Clip 3)
  • Modified the route configuration to follow more common standards with a base “products” route and paramMap in place of params. (Clip 4, 5. 6, 7)
  • Added the edit guard in its own file, modified it to use the providedIn syntax (new in Angular v6) and removed the registration from the Angular module. (Clip 6, 7)

Module 8: Create, Read, Update and Delete (CRUD) Using Http

  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 1, 4)
  • Removed the Product List Filter pipe component from the slides because using a pipe to build a filter is no longer recommended. (Clip 2)
  • Removed the discussion of the step to register the service since now registration is part of the decorator (‘providedIn’). (Clip 2, 3)
  • Updated from HttpModule to HttpClientModule and from Http to HttpClient as per changes in Angular v4.3. (Clip 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
  • Updated RxJS to version 6 imports and pipeable operators. (Clip 3, 5, 6, 7, 9, 11, 12, 13, 14 )
  • Re-recorded the demos to match the current sample code. (Clip 3, 4, 6, 7, 9, 11, 13)
  • Updated the information on installing the in memory web API since we are no longer using system.js. (Clip 4)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages. (Clip 5, 8, 10, 12)
  • Split clip 6 into 2 clips for a more reasonable clip length. (Clip 6, 7)
  • Replaced the Object.assign with the newer spread operator. (Clip 8, 9, 11)

Module 9: Final Words

  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 1)
  • Changed from “Angular 1” to “AngularJS” on the slides. (Clip 2)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages. (Clip 2)
  • Added references to Intermediate Angular courses for more information. (Clip 3)

Enjoy!

July 11, 2018

Angular: Getting Started Course Update (for v6)

Filed under: Angular,Angular CLI @ 5:19 pm

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 v4.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 v4.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.

Angular v6 was released on May 3, 2018. There was very little changed in Angular, but RxJS changed significantly as did Bootstrap. So time for another update to this course. This update was provided as a patch to the existing course and was published to the Pluralsight library on July 11, 2018.

The key changes include:

  • Update to Bootstrap v4 and Font Awesome (since Bootstrap no longer provides icons).
  • Update to the Angular CLI v6, which slightly changed the folder structure.
  • Update to RxJS v6, which includes new import statements and pipeable operators.
  • Modified to use the new providedIn property of the Injectable decorator to register services.
  • Modified to use the new currency pipe parameters.
  • Added additional required setup steps for those that don’t use my starter files.

The detailed changes to this course include:

Module 1: Introduction

  • Resized image to full screen. (Clip 1)
  • Replaced Discussion slide with current screen shot. (Clip 3)
  • Added a callout around the URL for the github repo. (Clip 3) Some viewers were finding older versions of the code that other developers had created instead of finding the DeborahK github repo with the correct files. https://github.com/DeborahK/Angular-GettingStarted
  • Upgraded from Bootstrap 3 to Bootstrap 4 and Font Awesome which changed the visual appearance of the pages. (Clip 4)

Module 2: First Things First

  • Removed the word “recently” when referring to ES 2015. (Clip 2)
  • Updated the image of the VS Code web site. (Clip 3)
  • Updated the image, callout, and narration for installing npm. (Clip 4)
  • Removed the option to use the quick start files from the Angular team as that option has been deprecated. (Clip 5)
  • Updated the github screen shot. (Clip 5)
  • Updated the folder structure screen shot. (Clip 5)
  • Replaced the installation demo to include a check of the npm version and for the new v6 files that appear in the Explorer window. (Clip 6)
  • Replaced the demo due to the new v6 files and reordered the steps for clarity. (Clip 7)

Module 3: Introduction to Components

  • Replaced the first part of the demo due to the new v6 files. (Clip 6)
  • Replaced the demo due to the new v6 files and changed debugging layout. (Clip 8)
  • Removed the information about the providers array, since it is no longer generated by the CLI. (Clip 8)
  • Corrected old link to the course discussion page in the slides. (Clip 9)
  • Hid the cursor that popped up in the slides at the end of the clip. (Clip 9)

Module 4: Templates, Interpolation, and Directives

  • Updated screen shots in the slides to new Bootstrap 4 and Font Awesome display. (Clip 2)
  • Added demo steps to install Bootstrap 4 and Font Awesome and import their styles. (Clip 2)
  • Replaced demo due to new v6 files. (Clip 2, 3)
  • Replaced demo due to new v6 files and improved quick fix. (Clip 4)
  • Replaced demo due to Bootstrap 4 style classes. (Clip 5)
  • Replaced DOM images on the slides with current DOM structure. (Clip 6)
  • Replaced demo due to Bootstrap 4 style classes both in the code and in the browser. (Clip 6)
  • Replaced browser portion of the demo due to Bootstrap 4 styles. (Clip 7)
  • Adjusted the timing of the step numbers on the “Component as a Directive” slide. (Clip 8)

Module 5: Data Binding & Pipes

  • Removed the recommendation of property binding over interpolation since that is no longer the recommendation. (Clip 2)
  • Replaced demo due to Bootstrap 4 style classes. (Clip 2, 3, 4)
  • Updated slide to new currency pipe syntax. (Clip 5)
  • Replaced demo due to new currency pipe syntax. (Clip 5)
  • Updated slide to Bootstrap 4 style classes in the DOM. (Clip 6)
  • Updated slide to new currency pipe syntax. (Clip 6)

Module 6: More on Components

  • Replaced demos due to Bootstrap 4 style classes. (Clip 2, 3, 4, 5, 6)
  • Updated demos due to new currency pipe syntax. (Clip 5, 6)

Module 7: Building Nested Components

  • Updated slide due to Bootstrap 4 style classes. (Clip 1)
  • Updated slide due to Bootstrap 4 style classes and font awesome icons. (Clip 2)
  • Updated demo due to new currency pipe syntax. (Clip 2)
  • Replaced demo due to font awesome icons. (Clip 2)
  • Replaced demo due to new currency pipe syntax and font awesome icons. (Clip 3, 4, 5)
  • Replaced demo due to Bootstrap 4 style classes. (Clip 3, 4, 5)
  • Added a “Learning More” slide. (Clip 6)

Module 8: Services and Dependency Injection

  • Removed the discussion of the Injectable decorator being optional since it is now often needed for the new ‘providedIn’ feature of v6. (Clip 3)
  • Replaced this entire clip to cover the injection hierarchy, the new ‘providedIn’ feature of v6, and when to use the root application injector vs a component injector. (Clip 4)
  • Updated the slide to remove the underscore (“_”) from the private variable name since that is no longer a common practice. (Clip 5)
  • Replaced demo due to removal of the underscore (“_”). (Clip 5)
  • Replaced demo due to Bootstrap 4 style classes. (Clip 5)
  • Updated the slide to cover the new ‘providedIn’ feature of v6 in the checklist. (Clip 6)

Module 9: Retrieving Data Using Http

  • Updated slide to remove reference to ES 2016. (Clip 2)
  • Rearranged the slides for a better flow. (Clip 2)
  • Added two slides on composing operators with the pipe method. (Clip 2)
  • Split clip 3 into two separate clips.
  • Updated the slides to remove the underscore (“_”), add ‘providedIn’, and update the RxJS operators to RxJS v6. (Clip 3, 5)
  • Replaced demo due to removal of the underscore (“_”), added ‘providedIn’, and the update of the RxJS operators to RxJS v6. (Clip 4, 5, 7)
  • Added instructions to the demo for setting the path to the data JSON file in the angular.json file. (Clip 4)
  • Added display of the console to show the syntax error resulting from our code changes. (Clip 4, 5)
  • Split clip 6 into two separate clips.
  • Added a demo slide. (Clip 7)
  • Updated the slide and replaced the discussion of observable subscription, removing the comparison to promises. (Clip 6)
  • Moved the Learning More slide to before the summary. (Clip 8)

Module 10: Navigation and Routing Basics

  • Replaced the demos for the current version of the Angular CLI and Bootstrap 4 style classes. (Clip 2)
  • Replaced the screen shots due to Bootstrap 4 style classes. (Clip 3, 6)
  • Split Clip 4 into two separate clips.
  • Added a demo slide. (Clip 5)
  • Replaced the demo due to removed providers array. (Clip 5)
  • Replaced the demo due to Bootstrap 4 style classes and removed providers array. (Clip 6, 7)
  • Enhanced the callouts to show the connection between the routerLink directive’s array elements and the route configuration. (Clip 6)
  • Enhanced the callouts to show the shortcut syntax for the routerLink directive. (Clip 7)

Module 11: Navigation and Routing Additional Techniques

  • Replaced the screen shots due to Bootstrap 4 style classes. (Clip 2, 4)
  • Split clip 2 into two separate clips.
  • Updated slide to remove underscores (“_”) in the variable names. (Clip 2, 4, 7)
  • Added a demo slide. (Clip 3, 6)
  • Replaced the demo due to removed providers array, changes to the currency pipe, removal of the underscores (“_”), and the Bootstrap 4 style classes. (Clip 3, 4)
  • Split clip 5 into two separate clips.
  • Updated the slide to display code consistent with what the CLI generates, including a revised file name. (Clip 5)
  • Replaced the demo using the current Angular CLI `generate guard` feature. (Clip 6)

Module 12: Angular Modules

  • Removed the services from the module diagrams and narration. (Clip 1, 8, 9, 12)
  • Replaced the demo due to removed providers array. (Clip 2)
  • Added information to the slide recommending using the `provideIn` instead of the providers array and removed the last “truth”. (Clip 7)
  • Added a demo slide. (Clip 9)
  • Removed extra narration discussing incorrect automatically generated import statements since they are now generated correctly. (Clip 9)
  • Replaced the demo due to improvements to the importing process, removed providers array, and Bootstrap 4 style classes. (Clip 9)
  • Replaced the demo due to the revised Angular CLI features. (Clip 10)
  • Replaced the demo to match the prior demos in this module. (Clip 11)

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

  • Replaced the demo due to the modified output of the Angular CLI features. (Clip 2, 3, 4, 5, 6, 7)
  • Enhanced the size of the command prompt window to make it easier to see. (Clip 2)
  • Replaced the demo due to the changes to the file structures of the code generated by the current Angular CLI. (Clip 3)
  • Reordered the narration due to the change in order and layout of the files generated by the current Angular CLI. (Clip 3)
  • Removed narration references to “blueprints” since that term is no longer used with regard to Angular CLI schematics. (Clip 5, 8)

Module 14: Final Words

  • Resized image to full screen. (Clip 2)
  • Removed the services from the module diagrams and narration. (Clip 3)
  • Added more courses to the Learning More slide. (Clip 3)

Enjoy!

April 23, 2018

“Angular NgRx: Getting Started” Problem Solver

Filed under: Angular,Angular Course Problem Solver @ 12:58 pm
Tags: ,

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

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

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

  • APM-Demo0: The starter files for this course. Use this to code along with the course.
  • APM-Demo1: Completed files after the First Look at NgRX module. It demonstrates a very simple NgRx example.
  • APM-Demo2: Completed files after the Strongly Typing Actions with Action Creators module. It refactors the simple example to include developer tooling support and strong typing.
  • APM-Demo3: Completed files after the Working with Effects module. It adds an effect to retrieve data via http. NOTE: Once we move the data retrieval to actions and the store, the create, update, and delete operations no longer work. These features are implemented with the store in the next demo
  • APM-Demo4: Completed files after the Performing Update Operations module. It adds the code needed for create, update, and delete operations via http.
  • APM-Demo5: Completed files after the Architectural Considerations module. It implements the container/presentational component pattern and the OnPush change detection strategy.

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

December 19, 2017

“Angular Component Communication” Problem Solver

Filed under: Angular,Angular Course Problem Solver @ 11:34 am
Tags:

This blog post supports the sample code for the “Angular Component Communication” 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-Communication. The folders in this repo include:

  • APM–Start: The starter files. Use this as a starting point to code along with the course.
  • APM–Final: The completed files.
  • APM–FinalWithGetters: The completed files using getters instead of Subject and BehaviorSubject to accomplish the same objective. Use this to see an alternate completed solution for this course.

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

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.

UPDATE: 2/22/18 Added techniques for a more generic filter method that can filter any list.

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.

More Generic Filtering on Criteria Matching any Object Properties

Taking it another step further, you can make your filter method even more generic by allowing it to filter *any* list. For that, we pass in the desired list:

    performFilter(list: any[], filterBy: string | null): any[] {
        if (filterBy) {
            filterBy = filterBy.toLocaleLowerCase();
            return list.filter((item) =>
                Object.keys(item).some(prop => {
                    let value = item[prop];
                    if (typeof value === "string") {
                        value = value.toLocaleLowerCase();
                    }
                    return value.toString().indexOf(filterBy) !== -1;
                })
            );
        } else {
            return list;
        }
    }

This code is similar to the prior example, but passes in the list to sort. It has an extra check that ensures the filterBy has a value. If not, it simply returns the full list.

Note that this code uses the *any* type to work with any type of array. To strongly type the array, you can use a generic parameter as shown below:

    performFilter<T>(list: any[], filterBy: string | null): T[] {
        if (filterBy) {
            filterBy = filterBy.toLocaleLowerCase();
            return list.filter((item: T) =>
                Object.keys(item).some(prop => {
                    let value = item[prop];
                    if (typeof value === "string") {
                        value = value.toLocaleLowerCase();
                    }
                    return value.toString().indexOf(filterBy) !== -1;
                })
            );
        } else {
            return list;
        }
    }

This method is called as follows:

this.filteredProducts = this.performFilter<IProduct>(this.products, this.listFilter);

Generic Filtering on Criteria Matching a Specific Property

You may instead want a generic filter function that only matches one specific property as shown here:

    performFilter<T>(list: any[], prop: string, filterBy: string | null): T[] {
        if (filterBy) {
            filterBy = filterBy.toLocaleLowerCase();
            return list.filter((item: T) => {
                if (item.hasOwnProperty(prop)) {
                    let value = item[prop];
                    if (typeof value === "string") {
                        value = value.toLocaleLowerCase();
                    }
                    return value.toString().indexOf(filterBy) !== -1;
                }
            });
        } else {
            // No filter was provided so return the list
            return list;
        }
    }

This code requires the following parameters:

  • The list to filter
  • The string name of the property to use for the filtering
  • The string defining the filter criteria

The calling code would then look like this:

this.filteredProducts = this.performFilter<IProduct>(this.products, 'productName', this.listFilter);

The above code is filtering the list of products on the productName property using the defined filter criteria.

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!

    Next Page »

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