Skip to content

Commit 3d54de9

Browse files
committed
Responding to comments from reviewer @kara
1 parent 3025783 commit 3d54de9

File tree

4 files changed

+68
-48
lines changed

4 files changed

+68
-48
lines changed

src/demo-app/select/select-demo.html

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,32 @@
9696
</md-card-content>
9797
</md-card>
9898

99+
100+
<md-card>
101+
<md-card-subtitle>compareWith</md-card-subtitle>
102+
<md-card-content>
103+
<md-select placeholder="Drink" [color]="drinksTheme"
104+
[ngModel]="currentDrinkObject"
105+
(ngModelChange)="setDrinkObjectByCopy($event)"
106+
[required]="drinkObjectRequired"
107+
[compareWith]="compareByValue ? compareDrinkObjectsByValue : compareByReference"
108+
#drinkObjectControl="ngModel">
109+
<md-option *ngFor="let drink of drinks" [value]="drink" [disabled]="drink.disabled">
110+
{{ drink.viewValue }}
111+
</md-option>
112+
</md-select>
113+
<p> Value: {{ currentDrinkObject | json }} </p>
114+
<p> Touched: {{ drinkObjectControl.touched }} </p>
115+
<p> Dirty: {{ drinkObjectControl.dirty }} </p>
116+
<p> Status: {{ drinkObjectControl.control?.status }} </p>
117+
<p> Comparison Mode: {{ compareByValue ? 'VALUE' : 'REFERENCE' }} </p>
118+
119+
<button md-button (click)="drinkObjectRequired=!drinkObjectRequired">TOGGLE REQUIRED</button>
120+
<button md-button (click)="compareByValue=!compareByValue">TOGGLE COMPARE BY VALUE</button>
121+
<button md-button (click)="drinkObjectControl.reset()">RESET</button>
122+
</md-card-content>
123+
</md-card>
124+
99125
<div *ngIf="showSelect">
100126
<md-card>
101127
<md-card-subtitle>formControl</md-card-subtitle>
@@ -129,32 +155,5 @@
129155
</md-card>
130156
</div>
131157

132-
<div *ngIf="showSelect">
133-
<md-card>
134-
<md-card-subtitle>compareWith</md-card-subtitle>
135-
<md-card-content>
136-
<md-select placeholder="Drink" [color]="drinksTheme"
137-
[ngModel]="currentDrinkObject"
138-
(ngModelChange)="setDrinkObjectByCopy($event)"
139-
[required]="drinkObjectRequired"
140-
[compareWith]="compareByValue ? compareDrinkObjectsByValue : compareByReference"
141-
#drinkObjectControl="ngModel">
142-
<md-option *ngFor="let drink of drinks" [value]="drink" [disabled]="drink.disabled">
143-
{{ drink.viewValue }}
144-
</md-option>
145-
</md-select>
146-
<p> Value: {{ currentDrinkObject | json }} </p>
147-
<p> Touched: {{ drinkObjectControl.touched }} </p>
148-
<p> Dirty: {{ drinkObjectControl.dirty }} </p>
149-
<p> Status: {{ drinkObjectControl.control?.status }} </p>
150-
<p> Comparison Mode: {{ compareByValue ? 'VALUE' : 'REFERENCE' }} </p>
151-
152-
<button md-button (click)="drinkObjectRequired=!drinkObjectRequired">TOGGLE REQUIRED</button>
153-
<button md-button (click)="compareByValue=!compareByValue">TOGGLE COMPARE BY VALUE</button>
154-
<button md-button (click)="drinkObjectControl.reset()">RESET</button>
155-
</md-card-content>
156-
</md-card>
157-
</div>
158-
159158
</div>
160159
<div style="height: 500px">This div is for testing scrolled selects.</div>

src/lib/select/select-errors.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
*/
88

99
/**
10-
* Returns an exception to be thrown when attempting to change a s
11-
* elect's `multiple` option after initialization.
10+
* Returns an exception to be thrown when attempting to change a select's `multiple` option
11+
* after initialization.
1212
* @docs-private
1313
*/
1414
export function getMdSelectDynamicMultipleError(): Error {
@@ -24,3 +24,12 @@ export function getMdSelectDynamicMultipleError(): Error {
2424
export function getMdSelectNonArrayValueError(): Error {
2525
return Error('Cannot assign truthy non-array value to select in `multiple` mode.');
2626
}
27+
28+
/**
29+
* Returns an exception to be thrown when assigning a non-function value to the comparator
30+
* used to determine if a value corresponds to an option. Note that whether the function
31+
* actually takes two values and returns a boolean is not checked.
32+
*/
33+
export function getMdSelectNonFunctionValueError(): Error {
34+
return Error('Cannot assign a non-function value to `compareWith`.');
35+
}

src/lib/select/select.spec.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,17 @@ import {Subject} from 'rxjs/Subject';
2828
import {map} from 'rxjs/operator/map';
2929
import {MdSelectModule} from './index';
3030
import {MdSelect} from './select';
31-
import {getMdSelectDynamicMultipleError, getMdSelectNonArrayValueError} from './select-errors';
31+
import {
32+
getMdSelectDynamicMultipleError,
33+
getMdSelectNonArrayValueError,
34+
getMdSelectNonFunctionValueError
35+
} from './select-errors';
3236
import {MdOption} from '../core/option/option';
3337
import {
3438
FloatPlaceholderType,
3539
MD_PLACEHOLDER_GLOBAL_OPTIONS
3640
} from '../core/placeholder/placeholder-options';
41+
import {extendObject} from '../core/util/object-extend';
3742

3843

3944
describe('MdSelect', () => {
@@ -2728,20 +2733,24 @@ describe('MdSelect', () => {
27282733
fixture.detectChanges();
27292734
}));
27302735

2731-
it('should have a selection', () => {
2732-
const selectedOption = instance.select.selected as MdOption;
2733-
expect(selectedOption.value.value).toEqual('pizza-1');
2734-
});
2736+
describe('when comparing by value', () => {
27352737

2736-
it('should update when making a new selection', async(() => {
2737-
instance.options.last._selectViaInteraction();
2738-
fixture.detectChanges();
2739-
fixture.whenStable().then(() => {
2738+
it('should have a selection', () => {
27402739
const selectedOption = instance.select.selected as MdOption;
2741-
expect(instance.selectedFood.value).toEqual('tacos-2');
2742-
expect(selectedOption.value.value).toEqual('tacos-2');
2740+
expect(selectedOption.value.value).toEqual('pizza-1');
27432741
});
2744-
}));
2742+
2743+
it('should update when making a new selection', async(() => {
2744+
instance.options.last._selectViaInteraction();
2745+
fixture.detectChanges();
2746+
fixture.whenStable().then(() => {
2747+
const selectedOption = instance.select.selected as MdOption;
2748+
expect(instance.selectedFood.value).toEqual('tacos-2');
2749+
expect(selectedOption.value.value).toEqual('tacos-2');
2750+
});
2751+
}));
2752+
2753+
});
27452754

27462755
describe('when comparing by reference', () => {
27472756
beforeEach(async(() => {
@@ -2759,7 +2768,7 @@ describe('MdSelect', () => {
27592768
expect(instance.select.selected).toBeUndefined();
27602769
});
27612770

2762-
it('should not update the selection when changing the value', async(() => {
2771+
it('should not update the selection if value is copied on change', async(() => {
27632772
instance.options.first._selectViaInteraction();
27642773
fixture.detectChanges();
27652774
fixture.whenStable().then(() => {
@@ -2778,7 +2787,7 @@ describe('MdSelect', () => {
27782787
it('should throw an error', () => {
27792788
expect(() => {
27802789
fixture.detectChanges();
2781-
}).toThrowError('compareWith must be a function, but received null');
2790+
}).toThrowError(wrappedErrorMessage(getMdSelectNonFunctionValueError()));
27822791
});
27832792

27842793
});
@@ -3375,6 +3384,6 @@ class NgModelCompareWithSelect {
33753384
compareByReference(f1: any, f2: any) { return f1 === f2; }
33763385

33773386
setFoodByCopy(newValue: {value: string, viewValue: string}) {
3378-
this.selectedFood = Object.assign({}, newValue);
3387+
this.selectedFood = extendObject({}, newValue);
33793388
}
33803389
}

src/lib/select/select.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ import {Observable} from 'rxjs/Observable';
5252
import {Subscription} from 'rxjs/Subscription';
5353
import {fadeInContent, transformPanel, transformPlaceholder} from './select-animations';
5454
import {SelectionModel} from '../core/selection/selection';
55-
import {getMdSelectDynamicMultipleError, getMdSelectNonArrayValueError} from './select-errors';
55+
import {
56+
getMdSelectDynamicMultipleError,
57+
getMdSelectNonArrayValueError,
58+
getMdSelectNonFunctionValueError
59+
} from './select-errors';
5660
import {CanColor, mixinColor} from '../core/common-behaviors/color';
5761
import {CanDisable, mixinDisabled} from '../core/common-behaviors/disabled';
5862
import {MdOptgroup, MdOption, MdOptionSelectionChange} from '../core/option/index';
@@ -350,8 +354,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
350354
get compareWith() { return this._compareWith; }
351355
set compareWith(fn: (o1: any, o2: any) => boolean) {
352356
if (typeof fn !== 'function') {
353-
throw new TypeError(
354-
`compareWith must be a function, but received ${JSON.stringify(fn)}`);
357+
throw getMdSelectNonFunctionValueError();
355358
}
356359
this._compareWith = fn;
357360
if (this._selectionModel) {
@@ -753,7 +756,7 @@ export class MdSelect extends _MdSelectMixinBase implements AfterContentInit, On
753756
isUserInput ? correspondingOption._selectViaInteraction() : correspondingOption.select();
754757
this._selectionModel.select(correspondingOption);
755758
}
756-
759+
757760
return correspondingOption;
758761
}
759762

0 commit comments

Comments
 (0)