Dale Nguyen
Dale Nguyen

Reputation: 1980

Angular FormArray doesn't delete item when using removeAt

I have a FormArray with a list items under it. I want to create a button to remove an item under an ArrayForm. When I click the button, it clear the form value, but it doesn't remove the item from the front end. Not sure where i'm missing.

enter image description here

app.component.ts

export class AppComponent  {
  name = 'Angular2+ Reactive Form';
  testForm: FormGroup;
  classGridDisplayedColumns = [
    "radioButtons"
  ];
  data = {
    radioButtons: [
      {radio: 'Y'},
      {radio: 'N'},
      {radio: 'N'}
    ]
  };
  constructor(private readonly fb: FormBuilder){
    this.testForm = this.fb.group({
      radioButtons: this.fb.array(
        this.data.radioButtons.map(radioButton => this.generateRadioButtons(radioButton))
      )
    });
  }

  private generateRadioButtons(radioButton) {
    return this.fb.group({
      radio: [ radioButton.radio, Validators.required ],      
    })
  }

  deleteRow(index) {
    console.log('Delete row...');  
    (<FormArray>this.testForm.controls.radioButtons).removeAt(index);
  }

  onSubmit() {
    console.log(this.testForm);
  }
}

app.component.html

<form name="testForm" [formGroup]="testForm" (ngSubmit)="onSubmit()" novalidate>
  <div formArrayName="radioButtons">
    <table mat-table [dataSource]="testForm.controls['radioButtons'].controls">        
      <ng-container matColumnDef="radioButtons">
        <th mat-header-cell *matHeaderCellDef class="radio">Radio Buttons</th>
        <td mat-cell *matCellDef="let element; let i = index;" [formGroupName]="i" class="radio">    
          <mat-radio-group name="radio-{{i}}" formControlName="radio" required disableOptionCentering>
            <mat-radio-button value="Y">Yes</mat-radio-button>
            <mat-radio-button value="N">No</mat-radio-button>
          </mat-radio-group>    
          <button type="button" (click)="deleteRow(i)">Delelet Row</button>        
        </td>
      </ng-container>
      <tr mat-header-row *matHeaderRowDef="classGridDisplayedColumns; sticky: true"></tr>
      <tr mat-row *matRowDef="let row; columns: classGridDisplayedColumns;"></tr>
    </table>
  </div>
  <pre>{{ testForm.value | json }}</pre>
</form>

You can find the demo here: https://stackblitz.com/edit/angular2-reactive-form-table

Upvotes: 2

Views: 4225

Answers (1)

KShewengger
KShewengger

Reputation: 8269

You will need to get the instance of the Mat Table first using ViewChild then render the updated rows after deletion using this.matTable.renderRows():

Have updated your Stackblitz: Updated Stackblitz Demo

export class AppComponent  {

  @ViewChild(MatTable, { static: false }) matTable: MatTable<any>;

  ...

  deleteRow(index) {
     console.log('Delete row...');  
     (<FormArray>this.testForm.controls.radioButtons).removeAt(index);

     this.matTable.renderRows();   // Add this
  } 

}

Upvotes: 3

Related Questions