From 675c9df9c262af13fe3f324af3e5bf1158926631 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 10 Mar 2017 19:41:34 +0100 Subject: [PATCH] fix(autocomplete): "undefined" being displayed on empty control with ngModel (#3535) * fix(autocomplete): "undefined" being displayed on empty control with ngModel Fixes "undefined" being displayed as the autocomplete input's value, if the value is undefined and the input uses `ngModel`. Fixes #3529. * const --- src/lib/autocomplete/autocomplete-trigger.ts | 4 +- src/lib/autocomplete/autocomplete.spec.ts | 53 ++++++++++++++++++-- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index 1dbfe73991c5..3faa768e6c9c 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -292,8 +292,8 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy { } private _setTriggerValue(value: any): void { - this._element.nativeElement.value = - this.autocomplete.displayWith ? this.autocomplete.displayWith(value) : value; + const toDisplay = this.autocomplete.displayWith ? this.autocomplete.displayWith(value) : value; + this._element.nativeElement.value = toDisplay || ''; } /** diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index 26c609fc1c7d..f3cc906d2d60 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -5,7 +5,7 @@ import {MdAutocompleteModule, MdAutocompleteTrigger} from './index'; import {OverlayContainer} from '../core/overlay/overlay-container'; import {MdInputModule} from '../input/index'; import {Dir, LayoutDirection} from '../core/rtl/dir'; -import {FormControl, ReactiveFormsModule} from '@angular/forms'; +import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Subscription} from 'rxjs/Subscription'; import {ENTER, DOWN_ARROW, SPACE, UP_ARROW} from '../core/keyboard/keycodes'; import {MdOption} from '../core/option/option'; @@ -26,9 +26,14 @@ describe('MdAutocomplete', () => { dir = 'ltr'; TestBed.configureTestingModule({ imports: [ - MdAutocompleteModule.forRoot(), MdInputModule.forRoot(), ReactiveFormsModule + MdAutocompleteModule.forRoot(), MdInputModule.forRoot(), FormsModule, ReactiveFormsModule + ], + declarations: [ + SimpleAutocomplete, + AutocompleteWithoutForms, + NgIfAutocomplete, + AutocompleteWithNgModel ], - declarations: [SimpleAutocomplete, AutocompleteWithoutForms, NgIfAutocomplete], providers: [ {provide: OverlayContainer, useFactory: () => { overlayContainerElement = document.createElement('div'); @@ -863,6 +868,18 @@ describe('MdAutocomplete', () => { }).not.toThrowError(); }); + it('should display an empty input when the value is undefined with ngModel', async(() => { + const fixture = TestBed.createComponent(AutocompleteWithNgModel); + + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const input = fixture.debugElement.query(By.css('input')).nativeElement; + + expect(input.value).toBe(''); + }); + })); + it('should work when input is wrapped in ngIf', () => { const fixture = TestBed.createComponent(NgIfAutocomplete); fixture.detectChanges(); @@ -997,6 +1014,36 @@ class AutocompleteWithoutForms { } + +@Component({ + template: ` + + + + + + + {{ state }} + + + ` +}) +class AutocompleteWithNgModel { + filteredStates: any[]; + selectedState: string; + states = ['New York', 'Washington', 'Oregon']; + + constructor() { + this.filteredStates = this.states.slice(); + } + + onInput(value: any) { + this.filteredStates = this.states.filter(s => new RegExp(value, 'gi').test(s)); + } + +} + /** * Focuses an input, sets its value and dispatches * the `input` event, simulating the user typing.