Lessons: 67Length: 8.9 hours

Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

5.9 Observing Form State Changes

In this lesson you'll see how to use observables to listen for changes in either control value or form status. You'll also learn a little bit about what observables are and how they can be used.

1.Introduction
6 lessons, 42:00

1.1
Introduction
00:48

1.2
Get Started With Angular-CLI
11:09

1.3
Developing With Angular-CLI
13:17

1.4
TypeScript vs. JavaScript
06:54

1.5
Angular Modules From the CLI
04:31

1.6
CLI Options
05:21

2.Get Started With Angular
7 lessons, 42:38

2.1
Bootstrapping the Application
04:30

2.2
The Application Module
04:15

2.3
The Application Component
08:06

2.4
Component Styling
03:06

2.5
Global Styling
05:11

2.6
Creating a Component With the CLI
09:34

2.7
Creating a Service With the CLI
07:56

3.Core Concepts
7 lessons, 55:20

3.1
Component Trees
06:20

3.2
Dependency Injection
06:52

3.3
Content Projection
05:38

3.4
Component and Directive Lifecycle Methods
06:31

3.5
Component-Only Lifecycle Methods
05:28

3.6
Decorators
07:36

3.7
Models
16:55

4.Template Deep Dive
11 lessons, 1:10:56

4.1
Basic Data Binding With Interpolation
05:35

4.2
Property Bindings
07:07

4.3
Attribute Bindings
03:29

4.4
Event Bindings
08:16

4.5
Class and Style Bindings
05:44

4.6
The `NgClass` and `NgStyle` Directives
05:04

4.7
The `*ngIf` Directive
04:41

4.8
The `*ngFor` Directive
09:29

4.9
Inputs
05:33

4.10
Using Pipes in a Template
07:31

4.11
Using Pipes in a Class
08:27

5.Forms
10 lessons, 1:45:41

5.1
Handling User Input With Template Reference Variables
07:06

5.2
Template-Driven Forms
11:10

5.3
Template-Driven Forms: Validation and Submission
14:00

5.4
Reactive Forms
11:26

5.5
Using a `FormBuilder`
08:01

5.6
Reactive Validation With Built-in Validators
14:53

5.7
Creating Custom Validators for Template-Driven Forms
12:18

5.8
Creating Custom Validators for Reactive Forms
08:26

5.9
Observing Form State Changes
12:40

5.10
Working With the `@HostListener` Decorator
05:41

6.Routing
9 lessons, 1:15:10

6.1
Defining and Configuring Routes
07:53

6.2
Rendering Components With Router Outlets
10:14

6.3
Using Router Links for Navigation
05:25

6.4
Navigating Routes Using the Router
06:24

6.5
Determining the Active Route Using an Activated Route
07:16

6.6
Working With Route Parameters
10:42

6.7
Using Route Guards
07:36

6.8
Observing Router Events
10:55

6.9
Adding Child Routes
08:45

7.Using the HTTP Client
5 lessons, 56:24

7.1
Sending an HTTP Request
10:52

7.2
Handling an HTTP Response
11:22

7.3
Setting Request Headers
12:33

7.4
Intercepting Requests
09:04

7.5
Finishing the Example Application
12:33

8.Testing
10 lessons, 1:23:27

8.1
Service Unit Test Preparation
10:45

8.2
Unit Testing Services
13:24

8.3
Component Unit Test Preparation
12:35

8.4
Unit Testing Components
07:27

8.5
Unit Testing Component Templates
06:58

8.6
Unit Testing Pipes
04:41

8.7
Unit Testing Directives
04:56

8.8
Unit Testing Validators
04:48

8.9
Unit Testing Observables
11:37

8.10
Unit Testing HTTP Interceptors
06:16

9.Building for Production
1 lesson, 03:40

9.1
Building for Production
03:40

10.Conclusion
1 lesson, 01:32

10.1
Conclusion
01:32


5.9 Observing Form State Changes

Hi folks. In this lesson, we're going to look at how we can observe changes in the state of a form or individual form controls from within a component. There are multiple different ways that we can do this, ranging from simple event handling to more complex state change observables. If we want to observe the changes of a single element, like a text input. One way to do that is to use an event binding directly on the element. So, for example, if we wanted to be notified when someone typed into the telephone field in our feedback form. We could do something like this. And then we would need to add this handle input method to the component class. And let's go back to the browser now. As we start to enter characters into the input we start to see our logs in the console. So this approach works and it could be fine for simple situations, but there are problems with doing it this way. It's a reactive form, not a template driven form. So, it's not fantastic to go against that philosophy and start adding things in the template. Sure, it's only one event binding in this case, but what if we wanted to watch all of the inputs for changes? Now there are more bindings and the template is even more complex. I mean it's pretty complex as it is anyway. Partly that's because of my screen resolutions. But it's still pretty complex. So the last thing that we wanna do is make that more complex. This technique also relies on passing the event object. There are ways around this, sure. We could use a template reference variable to avoid passing the event object. But then there's even more stuff going into the template. But also, this approach has other limitations. What if we don't want our handler to be invoked on every single keypress? We'd need to add our own debouncing logic into the component and that would make the component more complex, as well as the template. So event binding works but it's basic and it has limitations. A better way would be to observe changes in the control from within the component and then we don't have to change the template at all. So let's get rid of the binding in the template. And we can get rid of the handler back in the class. Angular creates a number of things that we can use to subscribe to changes in our forms. One of these is called value changes, and we can subscribe to this in order top be notified whenever the controls value changes. Let's add a subscription in the ng on Init method for changes in the telephone inputs. We can get the control that we are interested in using the useful get method, and we parse it the name of the control that we want to get, just like if we were using that in a template which we have done previously. All controls have these value changes property which contains an observable that we can subscribe to using the subscribe method. This method takes a callback, which we used an arrow function for in this example. This handler has passed the value that changed. So let's save that, and let's go back to the browser again. And it's pretty much the same as before. We can see the console log statement every time we press a key. So, personally, I think this is already a big improvement. First of all, all of the changes are in one place. They're not split between the component and the template. Also, we don't have to work with the complex event object. We receive only the value which changed in the callback. These are already big benefits. But also, the whole observable concept gives us access to much more powerful tools. Let's say that we want to delay the console log so that we don't get the value change on every single keystroke. With observables this is easy. We just need to import the helpful debounce time operator from RXJS. Now we can pipe this function to our observable. The debounds function delays the firing of the observable by the specified number of milliseconds. So let's go back to the browser now. So this time we can type five or six characters easily before we see the first console log. Okay so now you've seen some of the benefits let's take a moment to clarify what observables actually are. Observables are similar conceptually to promises. And they're useful for asynchronous code, just like promises. We're interested in handling some event at some future point but we don't know when. So we can add a handler that will be in vote at some future point whenever that event occurs. The difference between observables and promises is that promises are intended for a single result at some future point. Whereas observables are intended for a stream of possibly many results at many future points. In our example here, a promise would not be suitable for watching value changes, because there could be many value changes. Observables also have a much richer API than promises, and can be retried, canceled, and much, much more. This brings me to the next point about observables. Unsubscribing. We've subscribed to these value changes inside the ngOnInit method, and this method will be fired every time the component is initialized. Which for us is every time the feedback form is opened. Look, if we add a console log to the top of ngOnInit. And now go back to the browser. We can see that we see that console log every single time the feedback form is opened. The point here is that we could end up with memory leaks. Angular takes care that we aren't adding multiple subscriptions for the same event, so we shouldn't any duplicate logs for the value changes, but in more complex forms I've experienced these memory leaks firsthand. And so it can happen and it can cripple an application if not handled properly. What we should do is cancel the subscription when we're done with the component. Thankfully this is incredibly easy to do. So first of all, let's bring some extra type information into our component. This also comes from the RxJS library, which is a separate third party library but comes included with Angular. We also need to bring in another of Angular's lifecycle methods. We already have the Oninit interface but we'll need the ondestroy interface as well. And let's add that to the list of interfaces that the class implements. And now we need to add an ng on destroy method. We'll populate this method in just a moment. Okay, so when we subscribe to something, the subscribe method returns an observable. And this is what we'll need to unsubscribe. So we'll need to store this as a property of the component. We don't need to expose this proxy to the template or outside of the component at all, so we can keep it private, and it will be of the type subscription. So now when we bind to value changes, we just need to capture the return and store it in this property. And now we can fill out the ng on destroy method. All we need to do to dispose of the subscription, is call the unsubscribe method of the subscription objects. This simple line of code will help us to avoid any impacts on performance due to memory leaks. It's recommended to always unsubscribe from any subscriptions of observables that we create. Okay, so although interesting we don't need to watch our telephone input for value changes. Let's make a slight change to see that we can also subscribe to status changes of the form itself. Okay, so this time we are binding to status changes on the entire form. Although you should note that you can do this for individual form controls as well. This time the callback function receives the status of the form as an argument. And if we go back to the browser now. We should start to see locked messages of the form status which is currently invalid. And now we can see that the last few log messages say valid because once we filled out the form correctly, the form should become valid. So, this can be extremely useful to monitor when the form becomes valid. Again, this example is purely to show you these concepts. We don't need this in this particular form, so let's go ahead and remove everything that we've added so far in this lesson. Or, if you prefer, you can just comment now and play around with it later. So, I just want to remind you that observables aren't a part of Angular. They are a part of this external third-party library called RxJS, and we used one of the operators from this framework, the. As well as this, there are many, many others. So this webpage shows all of the RxJS version 5 operators that can be used. You can see there are many, many of them. For all kinds of different situations. So I'd recommend that you come back here at some point and just have a look through some of these. And also if you want to learn a bit more about RxJS itself, and observables in general, this site also contains a wealth of information all about RxJS. So in this lesson we saw how to watch either a form or individual form controls for either value changes or status changes using the concept of observables. We've seen how to use the subscribe methods where they handler for events that we want to observe. We've seen how to use operators like Debounce time, and we've learned we should always unsubscribe from observables when we no longer need them. Thanks for watching.

Back to the top