Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mat-select not pre selecting a value when mat-option has async content #7923

Closed
Almar opened this issue Oct 20, 2017 · 13 comments · Fixed by #9159
Closed

mat-select not pre selecting a value when mat-option has async content #7923

Almar opened this issue Oct 20, 2017 · 13 comments · Fixed by #9159
Assignees
Labels
P2 The issue is important to a large percentage of users, with a workaround

Comments

@Almar
Copy link

Almar commented Oct 20, 2017

Bug, feature request, or proposal:

Bug

What is the expected behavior?

When the ngModel of a mat-select is populated on page load the mat-select should have that option selected.

What is the current behavior?

mat-select does not show the current selected option on page load if a mat-option has some async behaviour, in my case the translate pipe:

        <mat-option *ngFor="let option of options" [value]="option.value">
          {{ option.label | translate }}
        </mat-option>

The current selected option is shown the moment the mat-select gets focus.

What are the steps to reproduce?

Please have a look at the following StackBlitz example:
https://stackblitz.com/edit/angular-material2-issue-async-mat-option-label?file=app%2Fpet-select-async%2Fpet-select-async.component.ts

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

material beta 12
angular 4.4.3

@depyronick
Copy link

+1

@depyronick
Copy link

well #6970 (comment) this

@Almar
Copy link
Author

Almar commented Oct 23, 2017

Hey @p0d3r, #6970 seems to be something else entirely. It describes a situation where the options are generated dynamically. The OP was surprised that the selected value was 'lost' when a new set op options was assigned.
This issue concerns strange behaviour if the displayed value of an option is modified by a pipe that has some async logic, like ngx-translate's 'translate' pipe. If the pipe is removed, everything works as expected.

@lordgreg
Copy link

I'm having the exact same issue.

@josephperrott josephperrott added the P2 The issue is important to a large percentage of users, with a workaround label Nov 7, 2017
@sathyakps
Copy link

I am also having the same issue with Reactive forms Module.. Does anybody found the solution?

@crisbeto
Copy link
Member

The issue here comes from the fact that the displayed value of the select comes directly from the textContent of the option, however there's no way for the select to know whether that value has changed. It might be tricky to do this in a performant way, because it means that we'd either have to maintain a MutationObserver on each of the options in order to know that the text changed, or we'd have to check the textContent after every change detection cycle.

@lordgreg
Copy link

so basically... its an non-standard select html element which has the material design but less features? I'll stick to the default aka. normal select element then. doesn't make any sense not being able to show the default/selected at init.

@crisbeto
Copy link
Member

It is possible to have a preselected value, it's currently not possible to have the label change asynchronously after init.

@MichaelScottBurke
Copy link

Is it possible to trim the selected value? e.g., i'm choosing a country phone code and want to show the full country name in the menu but only the code after selected? have hunted through several threads with nothing definitive. thanks

@vovikdrg
Copy link

vovikdrg commented Dec 2, 2017

For now my workaround is like this
Get labels

this.translateService.get(['Dancers', 'DancerIndexArchive']).safeSubscribe(this, (value) => {
     this.options.push({ key: 'dancers', value: value.Dancers });
     this.options.push({ key: 'dancerIndexArchive', value: value.DancerIndexArchive });
   });

Bind in Template

 <mat-form-field>
      <mat-select formControlName="Type">
        <mat-option [value]="option.key" *ngFor="let option of options">
          {{ option.value }}
        </mat-option>
      </mat-select>
    </mat-form-field>

Alexandre-Carbenay added a commit to adhuc-projects/cena-old that referenced this issue Dec 17, 2017
Move language management into a dedicated language service
Add component in header to select current language

Use bootstrap select style and custom event management instead of mat-select because of angular/components#7923 issue and not trivial style configuration
@jraadt
Copy link

jraadt commented Dec 17, 2017

A terrible hack to use with dynamically loaded options that may or may not contain the currently selected item, but you want to show the select item info in the select trigger, is to always have the selected item as an option that is hidden.

<mat-option [value]="select.value" *ngIf="select.value" style="display: none">{{select.value}}</mat-option>

Or you could use [compareWith] and have it always return true as long as there is at least 1 option in your select box. Not sure which one is nastier.

crisbeto added a commit to crisbeto/material2 that referenced this issue Dec 29, 2017
Currently `mat-select` doesn't react to changes in the label of its options, which is problematic, because the option label might be populated at a later point by a pipe or it might have changed while the select is closed. These changes add a `Subject` to the `MatOption` that will emit whenever the label changes and allows the select to react accordingly.

Fixes angular#7923.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jan 12, 2018
Currently `mat-select` doesn't react to changes in the label of its options, which is problematic, because the option label might be populated at a later point by a pipe or it might have changed while the select is closed. These changes add a `Subject` to the `MatOption` that will emit whenever the label changes and allows the select to react accordingly.

Fixes angular#7923.
jelbourn pushed a commit that referenced this issue Jan 21, 2018
Currently `mat-select` doesn't react to changes in the label of its options, which is problematic, because the option label might be populated at a later point by a pipe or it might have changed while the select is closed. These changes add a `Subject` to the `MatOption` that will emit whenever the label changes and allows the select to react accordingly.

Fixes #7923.
crisbeto added a commit to crisbeto/material2 that referenced this issue Jan 23, 2018
Currently `mat-select` doesn't react to changes in the label of its options, which is problematic, because the option label might be populated at a later point by a pipe or it might have changed while the select is closed. These changes add a `Subject` to the `MatOption` that will emit whenever the label changes and allows the select to react accordingly.

Fixes angular#7923.
jelbourn pushed a commit that referenced this issue Jan 24, 2018
Currently `mat-select` doesn't react to changes in the label of its options, which is problematic, because the option label might be populated at a later point by a pipe or it might have changed while the select is closed. These changes add a `Subject` to the `MatOption` that will emit whenever the label changes and allows the select to react accordingly.

Fixes #7923.
jelbourn pushed a commit to jelbourn/components that referenced this issue Jan 29, 2018
Currently `mat-select` doesn't react to changes in the label of its options, which is problematic, because the option label might be populated at a later point by a pipe or it might have changed while the select is closed. These changes add a `Subject` to the `MatOption` that will emit whenever the label changes and allows the select to react accordingly.

Fixes angular#7923.
@mehdibouzidi
Copy link

mehdibouzidi commented Dec 25, 2018

Hi, this solution I found is to set a value when we're going to initialize the view and also initializing our ReactiveForm, then when we retrieve the list of options with an Async call we reset the value in the "complete" callback:

  1. INITIALIZATION:
  ngOnInit() {
    this.editForm = this.fb.group({
      motif:[this.sanction.motif,[
        Validators.required
      ]],
      commentaire: [this.sanction.commentaire,[
      ]],
      type: [null,[
        Validators.required
      ]]
    });

  }

2.RESET:

constructor(public dialogRef: MatDialogRef<EditSanctionComponent>,
              @Inject(MAT_DIALOG_DATA) public sanction: Sanction,
              private fb: FormBuilder,
              private typeSanctionService: TypeSanctionService
  ) {
    console.log("CONSTRUCTOR EDIT SANCTION");
    this.typeSanctionService.getTypeSanctionList().subscribe(results => {
        this.typeSanctionOptions = results;
        console.log("SUBSCRIBE OPTIONS----");
      },
      () =>{},
      ()=>{
      console.log("ON COMPLETE CALL");
      const typteToSelect = this.typeSanctionOptions.find(itemType=> itemType.id === this.sanction.type.id);
        this.editForm.get('type').reset(typteToSelect);

      });
  }

Hope this will Help

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
P2 The issue is important to a large percentage of users, with a workaround
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants