Components: Autocomplete onSelectionChange fires two times when changing previously selected value

Created on 14 Apr 2017  路  15Comments  路  Source: angular/components

Bug:

If the autocomplete input field already has a value and this is changed by deleting the previous value and selecting a new option from the list, then the autocomplete's onSelectionChange fires twice.

What is the expected behavior?

When editing/ changing the previous selected value onSelectionChange should fire only once.

What is the current behavior?

When editing/ changing the previous selected value onSelectionChange fires twice

What are the steps to reproduce?

Step 1: Select a value from autocomplete dropdown
Step 2: Clear this value (use backspace/ select all and erase)
Step 3: Select a different value from the autocomplete

Providing a Plunker (or similar) is the best way to get the team to see your issue.
https://plnkr.co/edit/cOYg48HGf86ZtG0fO59r?p=preview

What is the use-case or motivation for changing an existing behavior?

When you want to edit a pre-filled value or you selected a value by mistake and want to make a change and if there are other fields dependent on this value, then the dependent values don't get updated.

Which versions of Angular, Material, OS, browsers are affected?

"@angular/material": "^2.0.0-beta.3"
OS: Mac
browser: Chrome/ Safari

Is there anything else we should know?

Nope.

P3 has pr

Most helpful comment

The onSelectionChange will fire two events one with isUserInput true and one with false.
This is a workaround:
(onSelectionChange)="selected($event, item.name)"

And in component:

private updateForm(_event: any, _name: any) {
        if (_event.isUserInput) {
           //do something        
        }

All 15 comments

:+1:

:+1: to this, having the same problem, what makes it worst is onSelectionChange emits newValue and then emits oldValue, the oldValue is what we get in the end.

The problem here is that the "onSelectionChange" is an event from the md-option component. What is really happening is that, when you select a new option on the md-autocomplete, it select the new option and then "deselect" the old one. You get the first event with the new option and the second event with the old option.

If you look at this Plunker (Open the console and change the options), you'll see that the first event will have an MdOptionSelectionChange event with evt.source.selected == true and the second one with evt.source.selected == false. If you use the md-select, you'll get even more events (included on plunker just as an example).

I've already created the issue #3645 to create an event for the md-autocomplete selectionChange, so we'll not need to rely on the md-options events.

For now, you can "fix" your problem by checking the evt.source.selected of the MdOptionSelectionChange event sent by the md-option

Thanks @jefersonestevo - was having the same issue and resolved it with your fix. Looking forward for the MD guys to release the much awaited "onOptionSelected" and "onBlurWithNoSelection" events!

Any ETA when this would be released?

Any ETA if / when this would be planned?

Any word on this update?

After updating to the latest release, I'm still getting 2 events fired. As explained in the previous comments, one seems to be the "selected" option and one seems to be the "deselected" option. Is this something that will not be fixed/changed?

In case others ran into the same problem, the workaround I used was checking the "isUserInput" attribute on the event which will only be "true" for the selected option event, but false for the "deselected" option.

That's because the same event fires for selecting and deselecting an option. If you want an event that only fires when an option is selected, you can subscribe to the MdAutocomplete.optionSelected event.

Ah I see, thank you!

Hi

I try to use it also but nothing happen when I write it on the <md-option>.

Example works with beta.10 :

<md-autocomplete #reactiveAuto="mdAutocomplete">
  <md-option (onSelectionChange)="onSelectedUser.emit(user)" *ngFor="let user of users$ | async">
    <span>{{user.login}}  -  {{user.firstName}} {{user.lastName}} ({{user.company}})</span>
  </md-option>
</md-autocomplete>

Example didn't work with beta.11 :

<md-autocomplete #reactiveAuto="mdAutocomplete">
  <md-option (optionSelected)="onSelectedUser.emit(user)" *ngFor="let user of users$ | async">
    <span>{{user.login}}  -  {{user.firstName}} {{user.lastName}} ({{user.company}})</span>
  </md-option>
</md-autocomplete>

Example works with beta.11 :

<md-autocomplete (optionSelected)="onSelectedUser.emit('rtyuio')" #reactiveAuto="mdAutocomplete">
  <md-option  *ngFor="let user of users$ | async">
    <span>{{user.login}}  -  {{user.firstName}} {{user.lastName}} ({{user.company}})</span>
  </md-option>
</md-autocomplete>

How to put it on the <md-option> to fire once the event and not twice like now ?
Or maybe I can get the user selected in the md-option and report it in the md-autocomplete ?
Might I miss something ? Thank you

The onSelectionChange will fire two events one with isUserInput true and one with false.
This is a workaround:
(onSelectionChange)="selected($event, item.name)"

And in component:

private updateForm(_event: any, _name: any) {
        if (_event.isUserInput) {
           //do something        
        }

see also this issue. I would like if this was fixed as it seems everyone tries to do it one way, only to find out that they have to use events instead. Sort of negates the point of 'onSelectedChanged' if 'optionSelected' is the only way to go.

@Swoox Gracias tu soluci贸n me sirvi贸 mucho.

Saludos!!

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings