import { Component , Input , Output , EventEmitter , ChangeDetectionStrategy , OnDestroy , OnInit } from "@angular/core" ; import { Subscription } from "rxjs/Subscription" ; import { BehaviorSubject } from "rxjs/BehaviorSubject" ; import { Product , WineComSearchResult } from "../../services/wineCom.service" ; import { FormControl } from "@angular/forms" ; import { StockSandbox } from "../../stock.sandbox" ; @ Component ( { selector : "wine-search" , changeDetection : ChangeDetectionStrategy . OnPush , template : `
        <div class="form-group has-feedback" [class.has-success]="control.valid">
            <label for="searchInput" class="col-sm-4 control-label">
                Name (*)
            </label>
            <div class="col-sm-8">
                <input type="text" [formControl]="control" class="form-control input-lg" id="searchInput" 
                    autocomplete="off" placeholder="Name"/>
                <span *ngIf="control.valid" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
                <ul class="wine-search-results">
                    <li *ngFor="let item of winesToShow$|async" (click)="onSelectWine(item)">
                        <img src="{{item.labels[0].url}}" alt=""/> {{item.name}} 
                    </li>
                </ul>
            </div>
        </div>
    ` } ) export class WineSearchContainer implements OnDestroy , OnInit { @ Input ( ) control : FormControl ; @ Output ( ) selectWine = new EventEmitter < Product > ( ) ; winesToShow$ = new BehaviorSubject ( [ ] ) ; private foundWineName : string ; private subscriptions : Array < Subscription > = [ ] ; constructor ( private sb ) { } onSelectWine ( wine ) { this . foundWineName = wine . name ; this . selectWine . emit ( wine ) ; this . winesToShow$ . next ( [ ] ) ; } ngOnDestroy ( ) { this . subscriptions . forEach ( sub => sub . unsubscribe ( ) ) ; } ngOnInit ( ) { let subscription = this . control . valueChanges . do ( ( value ) => { if ( value . length < 3 ) { this . winesToShow$ . next ( [ ] ) ; } } ) . debounceTime ( 300 ) . distinctUntilChanged ( ) . filter ( value => value . length > 2 && value !== this . foundWineName ) . switchMap ( value => this . sb . search ( value ) ) . map ( ( res ) => res . products . list ) . subscribe ( ( wines ) => { this . winesToShow$ . next ( wines ) ; } ) ; this . subscriptions . push ( subscription ) ; } }