Use RxJS Streams with Angular 2 Forms

John Lindquist
InstructorJohn Lindquist

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 4 years ago

Angular 2 forms provide RxJS streams for you to work with the data and validity as it flows out of the forms. These streams allow you handle complex scenarios and asynchronous scenarios with relative ease. This example shows you how to log out the values of the form when the form is valid.

[00:00] For many form, there are two streams available. To access the form, we need to use view child, look up that form ref through that reference, and then we'll just assign that to form. This is looking up this guy and bringing it down so we can control it programmatically.

[00:18] We can access that in NG after view init because at this point in this lifestyle hook, the view is ready to go. We can say this.form, and then the form has a stream called value changes. We can subscribe to that and just log out or we'll table out just to give it nicely formatted the results.

[00:40] I'll bring up the Chrome dev tools. You can see that it's logging out as I change these. I'll type password. You can see we have our object with a log in of username John and password pass right now. Every time this form changes, it's going to pass these value changes along.

[00:56] There's also a stream called status changes. I'll just log this one out. This will actually log out every time the status of my form changes. Now it's invalid. It's back to valid, invalid, valid. You can check against these valid and invalid values.

[01:15] With a decent understanding of RxJS, you can build out some pretty complex streams. We'll just do a simple example where I say import RxJS, add observable, and I'll need combine latest. I'm going to need observable itself, so I'll say observable from RxJS observable. I'm also going to want filter, so I'll grab the operator filter.

[01:43] With these two operators and observable, I can build up something like we'll say observable, combine latest, and we'll want to combine this.form.statuschanges and this.form.valuechanges. We'll combine these, so I'll have a status and a value and combine these into an object of status and value.

[02:09] On this I can filter. This will pass that object of status and value. But I'm only going to want the status on there. If status is valid, then I want to print out the value of that object. I'll console table value.

[02:30] If I save and bring up the dev tools, I'll clear this out, you can see I'll only get changes when I'm making changes and the field is still valid.

[02:40] I got JO but once I went less than JO, you'll see I'm making changes in the field that's invalid but I'm not getting them because I'll only get changes pushed through when the field is value. For this example, you could add this to local storage every time someone put in a valid change to the form and save it and ignore any changes to the form that were invalid.

[03:02] They could always revert back to a valid state of the form.

Morgan
Morgan
~ 6 years ago

you need to mention that you import ViewChild from angular core

rkrisztian
rkrisztian
~ 5 years ago

Do you really need to import the combineLatest operator if you use it as Observable.combineLatest, rather than as this.form.statusChanges.combineLatest? Coz I don't think so.

Prem Prakash
Prem Prakash
~ 4 years ago

combineLatest here also prints the 'INVALID' form status even after filtering. Possibly because first the valueChange event happens with the latest on status still being VALID. So even when the value becomes invalid, form status is still VALID and hence the invalid value still passes through the filter and gets printed in console. I don't know how to fix this. It will be good to know the fix though.

sxlwar
sxlwar
~ 4 years ago

@Prem Use zip instead of combineLatest will fix this issue.

Guru Inamdar
Guru Inamdar
~ 3 years ago
 const a$ = combineLatest(
      this.form.statusChanges,
      this.form.valueChanges,
      (status, value) => ({status, value})
    );
    a$.pipe(
      filter(({status}) => status === 'VALID')
    )
      .subscribe(({value}) => console.table(value));
Guru Inamdar
Guru Inamdar
~ 3 years ago

although 7 has deprecated warning on combineLatest