How to bind mat-chip to ngmodel in Angular 6 with Material

samhot picture samhot · Jun 26, 2018 · Viewed 9k times · Source

I have a form in a mat-dialog who displays multiple fields. Most of them are input and work perfectly, they are binded with [(ngModel)] as shown below, but I would like a field with mat-chips and autocomplete (like here). My problem is that I don't know how to bind the selected chips with [(ngModel)] get the data.

My HTML :

<form class="mat-dialog-content" (ngSubmit)="submit" #formControl="ngForm">
<div class="form">
  <mat-form-field color="accent">
    <input matInput #inputname class="form-control" placeholder="Nom du WOD" [(ngModel)]="data.name" name="name" maxlength="50" required >
    <mat-error *ngIf="formControl.invalid">{{getErrorMessage()}}</mat-error>
    <mat-hint align="end">{{inputname.value?.length || 0}}/50</mat-hint>
  </mat-form-field>
</div>

<div class="form">
  <mat-form-field color="accent">
    <input matInput placeholder="Notes du coach" [(ngModel)]="data.coachesNotes" name="coachesNotes">
  </mat-form-field>
</div>

<div class="form">
  <mat-form-field class="chip-list" aria-orientation="horizontal">
    <mat-chip-list #chipList [(ngModel)]="data.movementsIds" name="movementsIds">
      <mat-chip
        *ngFor="let mouv of mouvs"
        [selectable]="selectable"
        [removable]="removable"
        (removed)="remove(mouv)">
        {{mouv}}
        <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
      </mat-chip>
      <input
        placeholder="Ajouter un mouvement..."
        #mouvInput
        [formControl]="mouvCtrl"
        [matAutocomplete]="auto"
        [matChipInputFor]="chipList"
        [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
        [matChipInputAddOnBlur]="addOnBlur"
        (matChipInputTokenEnd)="add($event)"
      />
    </mat-chip-list>
    <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selectedChip($event)">
      <mat-option *ngFor="let mouv of filteredMouvs | async" [value]="mouv">
        {{ mouv }}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</div>

<div mat-dialog-actions>
  <button mat-button [type]="submit" [disabled]="!formControl.valid" [mat-dialog-close]="1" (click)="confirmAdd()">Ajouter</button>
  <button mat-button (click)="onNoClick()" tabindex="-1">Annuler</button>
</div></form>

My component :

public confirmAdd(): void {
  this.dataService.addWod(this.data);
}

View of my filled form

When I click on the "add" button my item is added with all of the others fields but the "movementsIds" field is null as we can see in the console.

Thanks you in advance for any help you can bring me.

Answer

samhot picture samhot · Jun 27, 2018

For those who could have the same problem, I've found a solution.

Instead of bind the chip list to my "data.movementsIds" with [(ngModel)] I just pass the "mouvs" array to my "confirmAdd" function and then set the data.movementsIds with this array like that :

HTML :

  <mat-form-field class="chip-list" aria-orientation="horizontal">
    <mat-chip-list #chipList>
      <mat-chip
        *ngFor="let mouv of mouvs"
        [removable]="removable"
        (removed)="remove(mouv)">
        {{mouv}}
        <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
      </mat-chip>
      <input
        placeholder="Ajouter un mouvement..."
        #mouvInput
        [formControl]="movementsIds"
        [matAutocomplete]="auto"
        [matChipInputFor]="chipList"
        [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
        [matChipInputAddOnBlur]="addOnBlur"
        (matChipInputTokenEnd)="add($event)"/>
    </mat-chip-list>
    <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selectedChip($event)">
      <mat-option *ngFor="let mouv of filteredMouvs | async" [value]="mouv">
        {{ mouv }}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>

Component :

public confirmAdd(mouvs: Array<any>): void {
   this.data.movementsIds = JSON.stringify(mouvs);
   this.dataService.addWod(this.data);
}