Angular – MAT-SELECTION-LIST binding not working with FormGroup

angularangular-material2

I am trying to get MAT-SELECTION-LIST to work inside a reactive form, to make a checklist group, using FormBuilder to create a FormGroup with the relevant FormControl in it. Instinctively, I just want to have a simple control like this:

      this.clientForm= this.fb.group( {
    myOtherControl: [[]]
  })

and use it like this:

<form [formGroup]="clientForm">

<h1>
  FormGroup Value
</h1>
<pre>
  {{ clientForm.get('myOtherControl').value | json }}
</pre>
<mat-selection-list id='2' formControlname="myOtherControl">
  <mat-list-option value="SOMETHING3">
    SOMETHING3
  </mat-list-option>
  <mat-list-option value="SOMETHING4">
    SOMETHING4
  </mat-list-option>
</mat-selection-list>
</form>

The problem is I can't get this to register any changes – the value shown remains as an empty array. But if I just use a bare FormControl, it works and I see the changes reflected, for example:

    <h1>
  FormControl Value
</h1>

<pre>
  {{ myControl.value | json }}
</pre>
<mat-selection-list id='1' [formControl]="myControl">
  <mat-list-option value="SOMETHING">
    SOMETHING
  </mat-list-option>
  <mat-list-option value="SOMETHING2">
    SOMETHING2
  </mat-list-option>
</mat-selection-list>

See https://stackblitz.com/edit/angular-material2-issue-yv1qaq for an example. Does anyone have any ideas what is going on here? I am on Angular 6/Material 6. I know there have been various issues with selectedOptions etc, but it looks like they are fixed now and this should just work?

Edit – Sooo, this is bizarre. As was pointed out in the comments, my example actually works if you correct the type on FormControlName. But that was just a typo, my actual code still wasn't connecting. But I could now see from the example that it should! So I decided to strip down my actual form to this just this one control and see if anything could coerce it into connecting to its formControl. Believe it not, taking out a Flex Layout attribute on a surrounding div fixed it! And to top it off, this isn't reproducible in the stackblitz example, even with exact same versions of material and flex-layout. Totally freaky, wasted hours on this. So basically, in my HTML context (a pop up dialog box), this doesn't work :

        <form [formGroup]="clientForm">
     {{ clientForm.get('geos').value | json }}
     <mat-selection-list
       formControlName="geos"
       (selectionChange)="onActivitySelected($event)">

        <div fxLayout="row">
          <mat-list-option *ngFor="let geo of data.geos"
                       [value]="geo.id">
        {{geo.id}} {{geo.text}}
         </mat-list-option>
       </div>
     </mat-selection-list>
   </form>

But this does:

<form [formGroup]="clientForm">
  {{client.geos}}
  <!--GEOS-->
  {{ clientForm.get('geos').value | json }}
  <mat-selection-list
    formControlName="geos"
    (selectionChange)="onActivitySelected($event)"
    fxLayout="row">
    <div >
      <mat-list-option *ngFor="let geo of data.geos"
                       [value]="geo.id">
        {{geo.id}} {{geo.text}}
      </mat-list-option>
    </div>
  </mat-selection-list>
</form>

Moving the fxLayout="row" from the div to the mat-selection-list made it work – frightening!

Best Answer

This is an interesting problem indeed. I ran into it as well. I was able to fix it with doing this:

// component.ts
this.clientForm = this.fb.group( {
    myOtherControl: new FormControl([]) 
});

// component.html
<form [formGroup]="clientForm">
   <pre>
     {{ clientForm.get('myOtherControl').value | json }}
   </pre>

   <mat-selection-list formControlName="myOtherControl">
     <mat-list-option value="SOMETHING3">SOMETHING3</mat-list-option>
     <mat-list-option value="SOMETHING4">SOMETHING4</mat-list-option>
   </mat-selection-list>
</form>

For some reason you might get a complain from the IDE that formControlName is an unknown attribute of mat-selection-list but it seems to be working just fine.

Here is an example: https://stackblitz.com/edit/angular-material2-issue-gnwvxq

Related Topic