title: How is it working this Angular pipe used to perform a dynamic search of terms inserted into an input tag in my view?
body: <p>I am very new in Angualar and I am following this official Angular tutorial: <a href="https://angular.io/tutorial/toh-pt6" rel="nofollow noreferrer">https://angular.io/tutorial/toh-pt6</a></p>
  
  <p>and I have some doubts about how it works, this is my commented code of the <strong>HeroSearchComponent</strong> class:</p>
  
  <pre><code>import { Component, OnInit } from '@angular/core';
  
  import { Observable, Subject } from 'rxjs';
  
  import {
     debounceTime, distinctUntilChanged, switchMap
   } from 'rxjs/operators';
  
  import { Hero } from '../hero';
  import { HeroService } from '../hero.service';
  
  @Component({
    selector: 'app-hero-search',
    templateUrl: './hero-search.component.html',
    styleUrls: [ './hero-search.component.css' ]
  })
  export class HeroSearchComponent implements OnInit {
  
    // It is an Observable emitting an array of Hero objects:
    heroes$: Observable&lt;Hero[]&gt;;
  
    /**
     * The searchTerms property is declared as an RxJS Subject.
     * A Subject is both a source of observable values and an Observable itself. 
     * You can subscribe to a Subject as you would any Observable.
     * You can also push values into that Observable by calling its next(value) method as the search() method does.
     */
    private searchTerms = new Subject&lt;string&gt;();
  
    constructor(private heroService: HeroService) {}
  
    /**
     * Push a search term into the observable stream.
     * Every time the user types in the textbox, the binding calls search() with the textbox value, a "search term". 
     * The searchTerms becomes an Observable emitting a steady stream of search terms. 
     */ 
    search(term: string): void {
      this.searchTerms.next(term);
    }
  
    ngOnInit(): void {
      this.heroes$ = this.searchTerms.pipe(
        // wait 300ms after each keystroke before considering the term
        debounceTime(300),
  
        // ignore new term if same as previous term
        distinctUntilChanged(),
  
        // switch to new search observable each time the term changes
        switchMap((term: string) =&gt; this.heroService.searchHeroes(term)),
      );
    }
  }
  </code></pre>
  
  <p>This class is used to search the heros from the <strong>hero-search.component.html</strong> containing:</p>
  
  <pre><code>&lt;div id="search-component"&gt;
    &lt;h4&gt;Hero Search&lt;/h4&gt;
  
    &lt;!--
      As the user types in the search box, a keyup event binding calls 
      the component's search() method with the new search box value
    --&gt;
    &lt;input #searchBox id="search-box" (keyup)="search(searchBox.value)" /&gt;
  
    &lt;ul class="search-result"&gt;
      &lt;!--
          The *ngFor iterates over a list called heroes$, not heroes.
          The $ is a convention that indicates heroes$ is an Observable, not an array.
          The *ngFor can't do anything with an Observable. 
          But there's also a pipe character (|) followed by async, which identifies Angular's AsyncPipe.
          The AsyncPipe subscribes to an Observable automatically so you 
          won't have to do so in the component class.
      --&gt;
      &lt;li *ngFor="let hero of heroes$ | async" &gt;
        &lt;a routerLink="/detail/{{hero.id}}"&gt;
          {{hero.name}}
        &lt;/a&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>Here my interpretation, I am absolutly not sure if it is correct or not.</p>
  
  <p>The <strong>heroes$</strong> field of the <strong>HeroSearchComponent</strong> is not an array but it is an <strong>Observable</strong> emitting an array. This because we live in an asyncronous world so we have to wait that the server provide the response.</p>
  
  <p>In the view I can't directly iterate on an array but I have to wait that I receive the response (when the previous Observable emit the array of <strong>Hero</strong>), this is done using the <strong>asyncornous</strong> pipe to register on this event:</p>
  
  <pre><code>&lt;li *ngFor="let hero of heroes$ | async" &gt;
  </code></pre>
  
  <p>This should be correct...</p>
  
  <p>Then into the view I have:</p>
  
  <pre><code>&lt;input #searchBox id="search-box" (keyup)="search(searchBox.value)" /&gt;
  </code></pre>
  
  <p>When the user insert a new character into the input tag it is called the component <strong>search()</strong> method passing the value inserted into the input tag ("a", "ab", "abc", "ab", etcetc).</p>
  
  <p>This is the <strong>search()</strong> method:</p>
  
  <pre><code>search(term: string): void {
    this.searchTerms.next(term);
  }
  </code></pre>
  
  <p>Looking at it is not directly performing a search calling a backend service but it is pushing the received new term into the <strong>searchTerms</strong>.</p>
  
  <p>This <strong>searchTerms</strong> object is a <strong>Subject</strong>. From what I have understood a <strong>Subject</strong> is an object that can emit event (as an Observable**) and at the same time can receive a stream of evens (in this case a stream of terms eacht time that the user insert a new char into the view search input).</p>
  
  <p>But...how and where it is performed the call to obtain the heroes list matching with the inserted term?</p>
  
  <p>My idea is the following one: it is not directly do in this method but there is something like a pre-setted behavior. This is done when this class is instanced by the <strong>ngOnInit()</strong> method:</p>
  
  <pre><code>ngOnInit(): void {
    this.heroes$ = this.searchTerms.pipe(
      // wait 300ms after each keystroke before considering the term
      debounceTime(300),
  
      // ignore new term if same as previous term
      distinctUntilChanged(),
  
      // switch to new search observable each time the term changes
      switchMap((term: string) =&gt; this.heroService.searchHeroes(term)),
    );
  }
  </code></pre>
  
  <p>That basically says something like: call the <strong>heroService.searchHeroes(term)</strong> method (the method that perform the search on my backend) passing the <strong>term</strong> each time that the <strong>searchTerms</strong> receive\emit an event (that is the last term to search). In theory this pipe is setted to do it not for every char inserted but every 300ms to avoid to perform much call).</p>
  
  <p>I am not sure about this mechanism and how exactly this pipe works. </p>
  
  <p>What is the correct and complete interpretation?</p>