components: md-select does not display default (null) option text in mat-select-value
Bug, feature request, or proposal:
Bug
What is the expected behavior?
Select should display text associated with null/undefined value when provided
What is the current behavior?
Select displays nothing
What are the steps to reproduce?
http://plnkr.co/edit/i919jzNOoXhlPeN4hxxE?p=preview
What is the use-case or motivation for changing an existing behavior?
Adding a default option with text for a null value should result in displaying the text when the current model value is null.
For example, adding a default option with text “None”
<md-option>None<md-option>
should show “None” when the select list is closed.
Which versions of Angular, Material, OS, TypeScript, browsers are affected?
Angular: 4.3.4 Material: Beta 8
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 11
- Comments: 16 (5 by maintainers)
Closing as working as intended. As noted above, this was a deliberate choice made in the
mat-select
If providing a
<md-option [value]="undefined">None</md-option>
or<md-option [value]="null">None</md-option>
then I would think the intent is clear, even for untouched selects. Without those options, it’s clear that there is no associated text and the select should display a blank.It just seems unexpected when
<md-option [value]="someValue">Text</md-option>
would display the text while<md-option [value]="null">None</md-option>
does not.@willshowell md-select-trigger is invisible if value is undefined or null i cant show ‘All’ or 'Please Select … ’ on the md-select (MD_PLACEHOLDER_GLOBAL_OPTIONS float: ‘always’)
md-select
used to take the null option’s label in the older versions, but it was changed deliberately to the current behavior. The problem with showing the null value label is that it makes it look as if the select has a value, even though it doesn’t. If we went back to the old behavior it would mean that we’d have to show the empty option’s label for untouched selects as well (assuming that they start atundefined
).So what’s the recommendation when an item in your list has a ‘value’ that truly is null and you want it selected?
For example I have a list of dates for a search filter :
‘Today’, ‘Yesterday’, ‘Last 7 days’, ‘All’
The type of
[value]
is Date (could equally be number). I really want ‘All’ to have a value of null, because:(a) The alternative would be DateTime.MinValue or 9999999 (b) a null clearly means ‘no filter’ © that’s what gets passed to my service so it’s just easier
But I run into this issue.
I just don’t understand why IF an item with an explicit value of null exists (and the developer clearly added one with a null value) that they shouldn’t expect it to be auto selected.
You said “If we went back to the old behavior it would mean that we’d have to show the empty option’s label for untouched selects” - but so what! - this would ONLY be a problem if someone had added an option with a null value that wasn’t intended to be the default - and if that were really the case what were they expecting it to do - just give that item a non null value.
I really don’t see how the ‘old behavior’ leads to undesirable behavior because if you really don’t like it you can just give everything a value? Perhaps more to the point is I feel the ‘old’ way is a much more common situation (filtering being the prime example) - and also the expected behavior.
Maybe I have to make the type
Date|string
and just put"All"
for the value? I really wish I could put null and I’ve used many other dropdowns in the past which allowed null as a value without issue.Edit: For me the solution that worked was to use
''
for the value which allows it to be selected by default with reactive forms. Fortunately the code generated service I use does the following, so the falsy empty string automatically gets converted to undefined without any more work.I also think this is a poor design choice. I’m having the same issue in that the selection of the value ‘null’ actually is a valid option in itself and presented to the user as “Inactive” instead of just a blank field. Right now, I’m working around this by having the “placeholder” attribute being “Inactive”. But semantically that doesn’t feel right, more like a workaround than a deliberate choice. Also this doesn’t allow me to force the user to actively pick “Inactive” as an option, it’s always the default when nothing else is selected.
I also find this extremely frustrating and a prime example of when an opinionated framework takes things too far. NULL IS A VALID OPTION and an option with that exact value should absolutely appear rendered in the control and not just silently discarded. For that matter any exact equality should work, why impose this falsey / discard approach? It’s absurd. I’ve lost half a day trying to get this working and my solution has been hacky at best, since EVEN IF you use a
<mat-label>
, the control will take that over as well. This is seriously maddening and surprising at the same time, my experiences otherwise have not been like this. I hope this issue gets addressed because this most certainly is a concern.I have to do all kind of hacks to work around this issue. This is simply not consistent behavior - You show the mat-option with null value, you allow it to be selected but then you don’t show it as selected. As others suggested just threat it as a normal select option as long as it is defined otherwise if not defined then keep the current behavior.
This is a major disappointment for us. We’re migrating material1 to material2 and relied heavily on null options in selects to represent ‘Any’ for filtering. The problem is that now an ‘Any’ selection with an already bound null value will trigger an unnecessary change event. The best solution I see is from @simeyla which is to set the value to ‘’, but of course now our typing is hacky, e.g. boolean|string etc. so this hopefully something that will be addressed. For reference:
<mat-select formControlName="isActive" > <mat-option value="">Any Status</mat-option> <mat-option *ngFor="let i of lookup.status" [value]="i.value">{{i.text}}</mat-option> </mat-select>