Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

August 19, 2019

What Is a Higher-Order Observable?

Filed under: Angular,RxJS @ 12:11 pm
Tags: ,

One of the challenges of diving deeper into RxJS, or Reactive Extensions for JavaScript, is the terminology. We may know the basics of using RxJS, but to really understand how it works, we need a firm grasp of its vocabulary.

Let’s focus on answering these questions:

  • What *is* a higher-order Observable?
  • What are inner and outer Observables?
  • And what is the purpose of a higher-order mapping operator, such as switchMap?

By mastering these concepts, we can better leverage RxJS to build more declarative and reactive Angular applications.

Background

From the RxJS documentation at rxjs.dev:

RxJS is a library for reactive programming using Observables, to make it easier to compose asynchronous or callback-based code.”

With RxJS, we work with any stream of data in a consistent manner. The data can be simple types, such as numbers or strings; or complex types, such as an array of customers or messages. It can be the response returned from an HTTP request. The stream can come from user input such as mouse or keyboard events.  We can use RxJS to manage a stream of anything.

When talking about Observables, the terms Observable stream, Observable, or just stream all reference the same thing: the collection of data items.  Those data items can emit immediately (synchronously) or over time (asynchronously). The stream can emit a finite number of items, such as a set of numbers, or an infinite number of items, such as a timer ticking every 1000 milliseconds forever.

Observables are lazy, meaning they don’t emit any items until we subscribe to them. Observables continue to emit values until the stream completes, an error occurs, or we unsubscribe.

Working with a single stream of data is just the beginning. With RxJS we can collect and combine data from multiple sources and transform that data as needed for the user. We can cache data in the application to minimize hits to our backend server. We can easily react to user actions and state changes. We can compose all the streams for a view into one stream to simplify complex UIs. To get this power from RxJS, we need to understand its terminology.

Here is a simple example of an Observable. It uses the `of` creation function (static method) to define an Observable stream. When subscribed, the stream emits three numbers and completes. This is represented as a marble diagram that depicts each emitted item as a marble. The straight vertical line at the end represents the complete notification.

 

When working with a response from an Http request, your Observable may look more like this:

 

In this example, the HTTP get request returns an Observable that emits the HTTP response: an array of three products. The Observable then completes. I often refer to these types of Observables as “data Observables” because their purpose is to emit the data from an API endpoint via HTTP.

These are all examples of simple Observables. More formally, they can be called “first order Observables”. So what is a higher-order Observable?

Higher-Order Observables

A higher-order Observable is an Observable that emits other Observables. “Why?” you may ask.

Let’s answer that with an example. Say we retrieve product data and as part of that data we get a set of supplier ids. The users want to see the list of suppliers along with the product so they can quickly reorder when inventory is low. So given the supplier ids, we need to retrieve each supplier’s data.

Our first thought might be something like this:

 

The first Observable uses the `of` creation function to define an Observable stream with two numbers. This is the outer Observable. When each number is emitted, that number is mapped to an http get request that returns an Observable. This is the inner Observable. So we now have an Observable that emits other Observables. This is a higher-order Observable. We define a higher-order Observable whenever we use data emitted from one Observable to emit another Observable.

But, this code does not actually work. Do you see why?

In the code above, we subscribe to the outer Observable but we don’t subscribe to the inner Observable. Since Observables are lazy, they won’t emit until subscribed. So, despite the pretty marble diagram, our inner Observables will never actually emit. How do we fix that?

One thought might be something like this:

In the above code, we issue an Http get request to get a product’s data. This request returns our outer Observable. We subscribe to that Observable at the bottom of this code. These are marked in orange.

We process the product data within the outer Observable’s pipeline, defined with the pipe method. There, we use the `tap` operator and loop through each supplier id for the product, issuing an http get request to get the supplier data. This request returns an inner Observable for each supplier, which we subscribe to as shown in green.

This results in nested subscribes, which are problematic for several reasons. Looking at the above code, you can see how challenging it could be to unsubscribe from these Observables. It would be difficult to make this code more declarative. And how would this work with an async pipe?

This is where higher-order mapping operators can help.

Higher-Order Mapping Operators

High-order mapping operators transform higher-order Observables. They map each value from an outer Observable to a new inner Observable and automatically subscribe to, and unsubscribe from that inner Observable.

RxJS provides several higher-order mapping operators. You can recognize a higher-order mapping operator by its name, which ends in `map`, such as mergeMap and switchMap.

Let’s look at a few of them.

concatMap

The concatMap higher-order mapping operator *waits* for each inner Observable to complete before processing the next one. It concatenates the results of the inner Observables in sequence.

Here, the outer Observable emits two numbers and for each emitted number it calls http get. When the first number is emitted, the concatMap automatically subscribes to the first inner Observable and the http get request is issued. It then *waits* for the returned response. Once the first inner Observable completes, it emits the result to the result stream. Only then does it subscribe to the next inner Observable, issuing that get request. It again waits for the returned response. When all inner Observables complete, the result stream completes.

Use concatMap if you want to ensure that each inner Observable is processed one at a time and in order. This is a great technique to use when updating or deleting data to ensure each operation is processed in sequence.

mergeMap

The mergeMap higher-order mapping operator processes each inner Observable in parallel. It merges the results of the inner Observables as they complete.

This is the same example, but with mergeMap. The outer Observable emits two numbers and for each emitted number it calls http get. When each number is emitted, the mergeMap automatically subscribes to its inner Observable and issues each http get request. As each response is received, it is merged to the result stream. When all inner Observables complete, the result stream completes.

Because the inner Observables are processed in parallel, the result stream may not be in sequential order. If, in the above example, the http get request for supplier s3 took longer to execute, its result could be emitted to the result stream after supplier s7.

Use mergeMap for better performance since each inner Observable is executed concurrently, but only if the resulting order doesn’t matter.

switchMap

The switchMap higher-order mapping operator unsubscribes from any prior inner Observable and switches to any new inner Observable.

Again, using the same example but with switchMap. The outer Observable emits two numbers and for each emitted number it calls http get. When the first number is emitted, the switchMap automatically subscribes to the first inner Observable and the http get request is issued. When the next item is emitted, switchMap unsubscribes from the prior inner Observable and switches to the new inner Observable, subscribing to it. If an inner Observable completes, it emits the result to the result stream. When all inner Observables complete, the result stream completes.

Use switchMap to stop any prior inner Observable before processing the next one. This is useful for features such as type ahead or autocompletion when you want to stop prior processing when the user types the next character.

No More Nested Subscribes

Any time we use data emitted from an Observable to emit another Observable, we need to subscribe to both the source outer Observable and the emitted inner Observable. Instead of nested subscribes, we use higher-order mapping operators. Higher-order mapping operators map higher-order Observables and take care of subscribing and unsubscribing to the inner Observables so we don’t have to.

For More Information

To learn more about RxJS, check out my Pluralsight course: “RxJS in Angular: Reactive Development”. You can find it at this URL: https://app.pluralsight.com/library/courses/rxjs-angular-reactive-development

The “RxJS in Angular” course starts with key terms such as observer, Observable, and subscriber and describes how Observable operators work. It covers reactive patterns for collecting data using RxJS. It then dives deeper looking at several techniques for combining streams from multiple data sources and mapping the returned data to a user-friendly format. It demonstrates how to react to user actions by creating action streams using Subject and BehaviorSubject. It examines how to cache streams to minimize hits to the server. It walks through several higher-order mapping operators. And it demonstrates how to combine all the streams for a view to provide the detailed information users require.

To sign up for a free Pluralsight trial, check out this link: https://www.pluralsight.com/pricing/free-trial

March 11, 2019

Object-Oriented Programming Fundamentals in C#: 2019 Update

Filed under: Uncategorized @ 10:12 am

My “Object-Oriented Programming Fundamentals in C#” course takes you, step by step, through the principles and practices of object-oriented programming (OOP). The course provides you with the firm foundation in OOP that you need to progress to intermediate-level C# courses.

This course was originally published on July 8, 2014.

It was updated on March 11, 2019. You can find the list of changes here: OOP for C# Course Update (2019)

December 20, 2018

Angular Routing Course Update (for v7)

Filed under: Angular,Angular Course Updates @ 12:18 pm

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

History

The first release of the “Angular Routing” course was in March of 2017. It supported Angular 2.0 and did not use the Angular CLI (which was released a few days later).

On December 20, 2018, this course was updated to Angular v7.

The key changes include:

  • Change of all references from “Angular 2” to “Angular”.
  • Modified to use the Angular CLI as this course was originally recorded before the final release of the CLI. This also impacted the module on lazy loading as the files are now bundled at development time as well.
  • Update to Bootstrap v4 and Font Awesome (since Bootstrap no longer provides icons). This affected all screenshots, demos, and code walkthroughs that displayed Html.
  • Replaced param with paramMap, queryParams with queryParamMap, and preserveQueryParams with queryParamsHandling.
  • Added more information on exception handling in a resolver.
  • Replaced animation with animation libraries that were new in v4.3.
  • Modified to use the providedIn property of the Injectable decorator (new in v6) to register services.
  • Modified to use HttpClientModule (new in v4.3) in place of HttpModule.
  • Update to RxJS v6, which includes new import statements and pipeable operators.

The detailed changes to this course include:

General

  • Added more callouts throughout.
  • Removed some of the silence between slides/demos to shorten the clips and improve the flow.
  • Removed many of the fade transitions and eliminated the shadow from the callouts to better follow Pluralsight standards.

Module 1: Introduction

  • Upgraded from Bootstrap 3 to Bootstrap 4 and Font Awesome which changed the visual appearance of the pages. (Clip 2, 4)
  • Changed from “Angular 2” to just “Angular” in the narration and slides. (Clip 2, 5)
  • Changed from “localhost:3000” to “localhost:4200”, which is the Angular CLI default, in the slides and demos. (Clip 2, 4)
  • Updated from HttpModule to HttpClientModule on the slides. (Clip 3)
  • Updated the templateUrl paths to use the ‘./’ prefix. (Clip 4)

Module 2: Routing Basics

  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 2, 3, 4, 5, 6, 7)
    • Folder structure
    • Changed from “localhost:3000” to “localhost:4200”, which is the Angular CLI default.
    • Updated from HttpModule to HttpClientModule.
    • Updated the templateUrl paths to use the ‘./’ prefix.
  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 2, 4)
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages and style classes in the Html. (Clip 2, 3, 5, 6, 7, 8)
  • Changed the demo of adding the base path since it is now automatically added by the CLI. (Clip 3)

Module 3: Routing to Features

  • Updated from HttpModule to HttpClientModule on the slide. (Clip 1)
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 2, 4, 5, 6, 7)
    • Folder structure
    • Changed from “localhost:3000” to “localhost:4200”, which is the Angular CLI default.
    • Removed the Product List Filter pipe because using a pipe to filter is no longer recommended.
    • Removed the providers array from the feature modules and instead use the new providedIn property of the Injectable decorator to register services.
    • Added getters to expose the properties from the auth service to the template since the service instance is private to the component.
  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages and style classes in the Html. (Clip 2, 4, 5)
  • Added a demo slide. (Clip 6)

Module 4: Route Parameters

  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages and style classes in the Html. (Clip 1, 3, 4, 8, 9)
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 1, 2, 4, 5, 6, 7, 8, 9, 10, 11)
    • Changed from “localhost:3000” to “localhost:4200”, which is the Angular CLI default.
    • Removed the Product List Filter pipe because using a pipe to filter is no longer recommended.
    • Removed the providers array from the feature modules and instead use the new providedIn property of the Injectable decorator to register services.
    • Modified the parameters of the currency pipe to the latest format.
    • Updated from the params array to the paramMap get method.
    • Changed the interface name from IProduct to Product to match with TypeScript naming conventions.
    • Changed from let to const wherever possible.
    • Updated Http to the newer HttpClient.
    • Updated to RxJS to use its new import statements and pipeable operators.
    • Updated preserveQueryParams to queryParamsHandling.
    • Updated from queryParams to queryParamMap.
  • Add a demo title slide. (Clip 6)
  • Changed from “Angular 2” to just “Angular” in the narration. (Clip 6)

Module 5: Prefetching Data Using Route Resolvers

  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages and style classes in the Html. (Clip 1, 3)
  • Modified the slides to replace the SmartArt with standard Pluralsight templates. (Clip 2, 3)
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 4, 6, 7, 8, 9)
    • Folder structure
    • Registered the resolver using the providedIn property of the Injectable decorator instead of a module.
    • Updated from the params array to the paramMap get method.
    • Changed the interface name from IProduct to Product to match with TypeScript naming conventions.
    • Changed from let to const wherever possible.
    • Updated to RxJS to use its new import statements and pipeable operators.
    • Removed the Product List Filter pipe because using a pipe to filter is no longer recommended.
    • Modified to use the resolver structure with the error handling.
    • Added steps to demonstrate the error handling when running in the browser.
  • Added a clip on handling errors in the resolver service. (Clip 5)
  • Removed the demo that defined the resolver in the module’s providers array as that is not considered a best practice. (Clip 8)

Module 6: Child Routes

  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages and style classes in the Html. (Clip 2, 4, 5, 8)
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 3, 4, 5, 6, 7)
    • Removed the Product List Filter pipe because using a pipe to filter is no longer recommended.
    • Removed the providers array from the feature modules and instead use the new providedIn property of the Injectable decorator to register services.
    • Modified to match the changes in the prior module for better resolver error handling.
    • Changed the interface name from IProduct to Product to match with TypeScript naming conventions.

Module 7: Grouping and Component-less Routes

  • Upgraded to Bootstrap 4 which changed the visual appearance of the pages and style classes in the Html. (Clip 2, 3)
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 2, 3)
    • Modified to match the changes in the prior module for better resolver error handling.

Module 8: Styling, Animating, and Watching Routes

  • Upgraded to Bootstrap 4 and Font Awesome which changed the visual appearance of the pages and style classes in the Html. (Clip 2)
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 2, 3, 4, 5, 6)
    • Removed the work around since the routerLinkActive now works correctly on list items.
    • Added an override of the active style class for the nav-link because the default active class was too subtle.
    • Replaced the animation with the route animation features new in Angular 4.3.
    • Changed the spinner to use Font Awesome.
  • Modified the slides to replace the SmartArt with standard Pluralsight templates. (Clip 4)

Module 9: Secondary Routes

  • Upgraded to Bootstrap 4 and Font Awesome which changed the visual appearance of the pages and style classes in the Html. (Clip 2, 3)
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 3, 4, 5, 6, 7)
    • Modified to match the changes in the prior module for route animation.
    • Added getters to expose the properties from the service to the template since the service instance is private to the component.
    • Move the html for the message component to its own file.
    • Enhanced the UI of the message component.
    • Registered the message service using the providedIn property of the Injectable decorator instead of a module.
    • Changed from let to const wherever possible.
    • Changed “localhost:3000” to “localhost:4200”, which is the Angular CLI default.
    • Added a demo of why getters are needed to expose the properties from a service.

Module 10: Route Guards

  • Reformatted title slide to match Pluralsight standards. (Clip 1)
  • Corrected duplicate word on slides. (Clip 2)
  • Modified the slides to replace the SmartArt colors with standard Pluralsight colors. (Clip 2)
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 2, 3, 4, 6, 7)
    • Registered the guards using the providedIn property of the Injectable decorator instead of a module.
    • Used the Angular CLI to create the guards.
    • Added diagrams to illustrate the guard process.
    • Updated from the params array to the paramMap get method.
    • Removed the I from the interface names to match with TypeScript naming conventions.
    • Replaced Object.assign with the newer spread operator.
    • Changed from let to const wherever possible.

Module 11: Lazy Loading

  • Modified the Course Intro slide to include information on the added clip. (Clip 1)
  • Added a clip on how Angular builds and serves files to better understand how lazy loading works. (Clip 2)
  • Modified the slides to replace the SmartArt with standard Pluralsight templates. (Clip 3, 6, 7, 8)
  • Added a slide to summarize the benefits of lazy loading. (Clip 4).
  • Re-recorded the demos/slides to match the current sample code using the Angular CLI and Angular v7. (Clip 3, 4, 5, 6, 7, 8, 9)
    • At development time, the files for the application are now bundled similar to a production build, so the Network tab no longer displays each individual JavaScript file. It instead lists the bundles.
    • Updated from HttpModule to HttpClientModule.
    • Removed the Product List Filter pipe because using a pipe to filter is no longer recommended.
    • Removed the providers array from the feature modules and instead use the new providedIn property of the Injectable decorator to register services.
    • The folder path used in the loadChildren property now uses ‘./’ for relative routes.
    • Registered the service using the providedIn property of the Injectable decorator instead of a module.
  • Added a demo slide. (Clip 7)

Module 12: Final Words

  • Updated from HttpModule to HttpClientModule on the slides. (Clip 2)
  • Modified the course references. (Clip 3)
November 8, 2018

Angular: Getting Started Course Update (for v7)

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,Angular Course Updates @ 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)

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!

    Next Page »

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