@@ -314,7 +314,7 @@ h3#stream-integration Stream Integration
314
314
+ makeExcerpt('src/app/add-hero.component.1.ts (hero form component)' , '' )
315
315
316
316
:marked
317
- The hero form template is just getting started also .
317
+ And the hero form template.
318
318
319
319
+ makeExcerpt('src/app/add-hero.component.1.html (hero form template)' , '' )
320
320
@@ -326,10 +326,54 @@ h3#stream-integration Stream Integration
326
326
+ makeExcerpt('src/app/hero.service.4.ts (add hero)' , '' )
327
327
328
328
:marked
329
- If you look at the template closer , you'll see the `showErrors` boolean, which hides the error messages until you're ready to display them.
329
+ If you look at the template, you'll see the `showErrors` boolean, which hides the error messages until you're ready to display them.
330
330
A good form waits until the user has interacted with the fields before displaying any errors, and you'll want to follow that same rule. So
331
- how can you display errors once an interaction has happened? Reactive form controls provide an Observable stream of `valueChanges` whenever
332
- the form input changes and we can subscribe to that. Let's add
331
+ how can you display errors once an interaction has happened? Interaction on the input can be as simple as entering the field
332
+ and leaving the field, also known as the blur event. Observables can be created from existing events. You'll use the `fromEvent`
333
+ operator to create an Observable from the existing `blur` event on the hero name input field.
334
+
335
+ In order to access the input field, you'll need to add a template reference to to the element. The `heroName` template reference will
336
+ give us access to the input field in the component class. The updated template is as follows:
337
+
338
+ + makeExcerpt('src/app/add-hero.component.2.html (heroName template reference)' , '' )
339
+
340
+ :marked
341
+ Now that you can access the template reference, you'll need to import the `ViewChild` decorator, the `ElementRef` type
342
+ and the `AfterViewInit` lifecycle hook.
343
+
344
+ + makeExcerpt('src/app/add-hero.component.2.ts (ViewChild imports)' , 'viewchild-imports' )
345
+
346
+ :marked
347
+ You'll use the `ViewChild` decorator to target the `heroName` template reference in the component assigned to
348
+ the `ElementRef` type.
349
+
350
+ + makeExcerpt('src/app/add-hero.component.2.ts (ViewChild ElementRef)' , 'viewchild-heroName' )
351
+
352
+ :marked
353
+ As usual, you'll need to import a few instance and static operators to create the Observable event. As
354
+ previously mentioned, you'll use the `takeUntil` operator to clean up any Observable streams once the component
355
+ is destroyed. In order to create an Observable from an element event, the `fromEvent` observable creation operator
356
+ is needed. The `fromEvent` let's you create a stream from existing events emitted by elements. An additional operator
357
+ is the `merge` creation operator, which combines multiple streams together
358
+
359
+ + makeExcerpt('src/app/add-hero.component.2.ts (rxjs imports)' , 'rxjs-imports-1' )
360
+
361
+ :marked
362
+ In order to use the `ViewChild`, you'll need to implement the `AfterViewInit` interface and the `ngAfterViewInit`
363
+ lifecycle hook. The `Observable.merge` let's you compose multiple observables and will emit when any of the source
364
+ Observables emit a value without waiting for each one. You'll subscribe to the Observable and check the validity of
365
+ the form in order to show errors. Now when the user triggers the `blur` event on the input the errors will be displayed.
366
+
367
+ + makeExcerpt('src/app/add-hero.component.2.ts (Observable fromEvent)' , '' )
368
+
369
+ :marked
370
+ Since you can compose multiple streams using `Observable.merge`, you can easily add additional streams to trigger
371
+ the validation check. Since reactive forms provide an Observable of `valueChanges`, you can listen for value changes
372
+ from the `name` field and display errors once the user inputs some data also. You can easily access this through the reactive
373
+ forms getter. Update the merged observables to include the name valueChanges.
374
+
375
+ + makeExcerpt('src/app/add-hero.component.3.ts (Observable valueChanges)' , 'value-changes' )
376
+
333
377
h3#further-reading Further Reading
334
378
:marked
335
- TODO
379
+ // TODO link some resources
0 commit comments