book-monkey4 / iteration-3-rxjs

🐵📕 Das kleine Demo-Projekt – Finaler Stand aus Kapitel "10.2 Reaktive Programmierung mit RxJS"
https://iteration-3-rxjs-bm4.angular-buch.com/
0 stars 1 forks source link

Search field failed to compile #4

Open hoall opened 3 years ago

hoall commented 3 years ago

Hi,

first of all, awesome book. I like the style and learn quite good with it. In 10.2.12 seems to be an mistake regarding Angular 9 or newer.

Failed to compile.

src/app/search/search.component.html:3:85 - error TS2339: Property 'value' does not exist on type 'EventTarget'.

3     <input type="text" class="prompt" #searchbox (keyup)="keyUp$.next($event.target.value)">
                                                                                      ~~~~~

  src/app/search/search.component.ts:7:16
    7   templateUrl: './search.component.html',
                     ~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component SearchComponent.

https://github.com/book-monkey4/iteration-3-rxjs/blob/3af1fd77d5e7cdc1f095165445d23786dc3d3b96/src/app/search/search.component.html#L4

The issue was already discussed at the angular repository directly: https://github.com/angular/angular/issues/35293

My workaround for this is based on the linked description in the discussion https://angular.io/guide/user-input#get-user-input-from-a-template-reference-variable :

<input type="text" class="prompt" #searchbox (keyup)="keyUp$.next($event.target.value)">

Would be glad to hear what your solution would be.

Regards

fmalcher commented 3 years ago

Hi @hoall , thanks for the bug report! We didn't notice this issue since the stricter template checks were not available when we developed the example. As a workaround, I'd go with the following:

Capture the whole event object in the Subject:

keyUp$ = new Subject<KeyboardEvent>();
(keyup)="keyUp$.next($event)"> 

Then extract the value from there. The type assertion as HTMLInputElement is okay at this point because we can be sure it can ony be HTMLInputElement:

this.keyUp$.pipe(
  map(e => (e.target as HTMLInputElement).value)
  filter(term => term.length >= 3),
  // ...

However, as soon as you proceeded with the chapters about forms, I'd highly recommend to refactor this example and use reactive forms. The FormControl has a valueChanges property which is an Observable of values. You can use this directly as the source for this typehead search.

In fact, your described workaround is also cool. So choose whatever you like 🙂

<input type="text" class="prompt" #searchInput (keyup)="keyUp$.next(searchInput.value)">