angular: Select field in Safari displays option but does not set value when default value is null

I’m submitting a … (check one with “x”)

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior This happens with the Internet Explorer and older versions of Firefox (does happen in version 40, does not happen in version 50): When no default value (or explicitly null) is set for a select field’s form control, the first option is displayed in the UI but not set as value in the corresponding FormControl. Side note: Manually selecting the already displayed value does not set the FormControl’s value either. To select this option one must first select a different option and then the first one again, only then the value property is correctly set.

Expected behavior I’d expect the field to be empty initially. If this cannot be done, I’d at least expect the FormControl’s value property to be set correctly (reflecting the displayed value).

Minimal reproduction of the problem with instructions Create a select field with no default value and view in IE/older Firefox. Minimal example

Please tell us about your environment: Tested on Windows 7 and 10 using Chrome 56 and Firefox 50 (behave as expected) and Internet Explorer 11 and Firefox 40 (buggy)

  • Angular version: 2.4.7

  • Language: TypeScript 2.0.2

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 22
  • Comments: 28 (13 by maintainers)

Commits related to this issue

Most upvoted comments

There’s a template-only workaround which has so far worked quite well for me:

<form [formGroup]="form">
	<select formControlName="select">
		<option *ngIf="!form.value.select" [ngValue]="null" selected disabled></option>
		<option *ngFor="let option of options" [ngValue]="option">{{option}}</option>
	</select>
</form>

This will display a blank option while no value is set, which disappears as soon as another value is selected. (You may have to use "form.value.select === null" if your select has valid options that evaluate to false.)

Come across this myself, it is insane this has not been merged.

This bug still exists with Angular 8 and the latest version of Safari and IE 11. I rebased my pull request from last year which fixes it - hopefully it can be reviewed soon. I’m not sure what more to do to bring it to the attention of the Angular team.

I fixed this almost a year ago in pull request #23784, by setting selectedIndex to -1 if the browser didn’t already do so. However, there still hasn’t been any reply from the assigned reviewer. @kara @IgorMinar

This bug still exists in Angular 7.0.0, affecting both IE 11 and Safari 12.0.1.

Any updates on this?

I’ve dived a bit into this. This issue indeed only occurs when data is loaded dynamically through the [value] or [ngValue] attributes on <option> elements. Take a look at this example:

Chrome:

image

IE11/Safari on iOS 12.2:

image What seems to happen is that when the [value] or [ngValue] attributes are used, the following code is triggered (reference):

/**
   * @description
   * Tracks the value bound to the option element. Unlike the value binding,
   * ngValue supports binding to objects.
   */
  @Input('ngValue')
  set ngValue(value: any) {
    if (this._select == null) return;
    this._select._optionMap.set(this.id, value);
    this._setElementValue(_buildValueString(this.id, value));
    this._select.writeValue(this._select.value);
  }

  /**
   * @description
   * Tracks simple string values bound to the option element.
   * For objects, use the `ngValue` input binding.
   */
  @Input('value')
  set value(value: any) {
    this._setElementValue(value);
    if (this._select) this._select.writeValue(this._select.value);
  }

The writeValue() function has the following line:

const id: string|null = this._getOptionId(value);
if (id == null) {
  this._renderer.setProperty(this._elementRef.nativeElement, 'selectedIndex', -1);
}

The selectedIndex is key here. As you can see in the screenshots above, Chrome sets the selectedIndex to -1 again, while IE11/Safari don’t reset it to -1 but to 0 instead. This is then not synchronized with the form state, so the formControl value will still be null/empty string.

Hope this helps a bit to troubleshoot further, not sure how to proceed now. 😃

This problem does still exist with Angular v4.3.3. It is actually worse if the select box contains only one element. The option looks like selected, although it isn’t (in the model). If the select is required, it is not possible to get the form into valid state.

I have made another Plunker that shows how to reproduce it in template based forms. Please note that the problem occurs only if the option values are set delayed. So both

setTimeout(() => {
  this.offices = ['Office1'];
}, 1000);

and using let officeOptions of offices | async makes IE11 show the unselected item as selected.

This is interesting as the example of @janaleible does set the option values immediately and the bug still shows up.

@julisch94 I’ve been keeping pull request #23784 rebased whenever there are merge conflicts, but I haven’t heard anything new from the Angular team for a couple months. At the end of June they said they needed to investigate a couple places in Google’s codebase for forward compatibility, but there doesn’t seem to have been any progress since then. 😢 @AndrewKushnir @pkozlowski-opensource

@theodorejb It seems to be moving forward, thank you very much. For my project, I have now implemented the solution suggested above as a workarout: For Internet Explorer, an additional option has been added to each (!) select element, which disappears when the model gets a value.

This is ok for me for the moment, but integrating a general solution into Angular would of course be absolutely desirable.

This bug still exists with Angular 8 and the latest version of Safari and IE 11. I rebased my pull request from last year which fixes it - hopefully it can be reviewed soon. I’m not sure what more to do to bring it to the attention of the Angular team.

Many thanks @theodorejb for your commitment in this matter! I have a big project here with a lot of select dropdowns, all of which don’t work in IE because of this problem. The integration of your solution into Angular is progressing sluggishly (if at all)… Is there a way I can integrate your solution into my own project?

Note that this issue also affects the latest version of Safari, not just IE.

Here’s a minimal reproduction of the issue: https://angular-select-ie-bug.stackblitz.io.

A form value can be selected as expected in Chrome, Firefox, and Edge, but not Safari or IE 11.