Angular – How to setup Angular Material Chip Contol with reactive forms

angularangular-materialangular-reactive-forms

I have an Angular Reactive Form with Angular Materials

For all my controls I add the required validator.

I'm not sure how to setup the chips control correctly with reactive forms.

Where do you set the formControlName so that the required validator fires? At the moment I have it set on the input field which I'm guessing is wrong.

I just want the courseIds to be a comma seperated string with the course ids.

TS:

form: FormGroup;

ngOnInit() {
    this.form = new FormGroup({
      name: new FormControl("", [Validators.required]),
      courseIds: new FormControl("", Validators.required)
    });
  }

HTML:

  <form [formGroup]="form" (ngSubmit)="submit()">

    <mat-form-field>
      <input matInput type="text" formControlName="name" placeholder="Name">
    </mat-form-field>

    <mat-form-field>
      <mat-chip-list #chipList>
        <mat-chip *ngFor="let cid of courseIds" (removed) = "...">
          {{cid}}
        </mat-chip>

        <input matInput formControlName="courseIds"
               [matChipInputFor]="chipList" 
               placeholder="Ids" 
               (matChipInputTokenEnd)="add($event)">
      </mat-chip-list>
   </mat-form-field>    

....

    <button type="submit">OK</button>
  </form>

Best Answer

Try setting the formControlName at the <mat-chip-list> level.

In your template, set the ngFor to loop over the courseIds control value

<mat-form-field>
    <mat-chip-list #chipList formControlName="courseIds">
        <mat-chip *ngFor="let cid of form.get('courseIds').value" (removed) = "...">
            {{cid}}
        </mat-chip>

        <input matInput
            [matChipInputFor]="chipList" 
            placeholder="Ids" 
            (matChipInputTokenEnd)="add($event)">
    </mat-chip-list>
</mat-form-field>

Then in your component, create the form group with the initial values for courseIds if any, else use an empty array [] (since the chips display an array and not a string). In your add() and remove() function, add and remove the values from the courseIds control value respectively.

form: FormGroup;

ngOnInit() {
    this.form = new FormGroup({
        name: new FormControl("", [Validators.required]),
        courseIds: new FormControl([], Validators.required)
    });
}

add() {
    ...

    // Add new input to courseIds control value
    this.courseIds.value.push(value);

    this.courseIds.updateValueAndValidity();
}

remove() {
    ...

    // Remove element from control value array
    this.courseIds.value.splice(index, 1);    // where index = index of removed element

    this.courseIds.updateValueAndValidity();
}

// use getter method to access courseIds control value easily
get courseIds() { 
    return this.form.get('courseIds');
}
Related Topic