3

I have been trying to use multiTemplateDataRows with reactive forms and giving formArrayName in the table tag of the mat-table but getting the error as Cannot find control with path: 'bankRelationData ->,

But this works fine when i remove the multiTemplateDataRows directive from the table tag, Please find the below code

table.component.html

<form [formGroup]="bankRelationForm">
<table mat-table [dataSource]="dataSource" multiTemplateDataRows formArrayName="bankRelationData" class="mat-elevation-z8">
  <ng-container matColumnDef="position">
        <th mat-header-cell *matHeaderCellDef> No. </th>
        <td mat-cell *matCellDef="let element"> {{element.position}} </td>
    </ng-container>

  <ng-container matColumnDef="name">
        <th mat-header-cell *matHeaderCellDef> Name </th>
        <td mat-cell *matCellDef="let element"> 
      <div>
      {{element.name}} 
      </div>
      </td>
    </ng-container>

  <ng-container matColumnDef="weight">
        <th mat-header-cell *matHeaderCellDef> Weight </th>
        <td mat-cell *matCellDef="let element"> {{element.weight}} </td>
    </ng-container>

  <ng-container matColumnDef="symbol">
        <th mat-header-cell *matHeaderCellDef> Symbol </th>
        <td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
    </ng-container>

  <ng-container matColumnDef="secondary" >
     <td mat-cell [attr.colspan]="displayedColumns.length" *matCellDef="let element"> 
        <textarea></textarea>
     </td>
   </ng-container>

  <ng-container matColumnDef="actions">
        <th mat-header-cell *matHeaderCellDef>
       <button *ngIf="!isEdited" mat-raised-button color="primary" (click)="onEdit()">Edit</button> </th>
        <td mat-cell *matCellDef="let element; let i = index"> 
      <button *ngIf="isEdited" mat-mini-fab class="add-btn" matTooltip="Add comment" color="primary" (click)="onAdd(element.position)">+</button>
      <button *ngIf="isEdited" mat-mini-fab class="add-btn" color="warn" (click)="onRemove(element.position)">-</button>
       </td>
    </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row;let i=index; columns: displayedColumns;"
  [formGroupName]="i"></tr>
  <tr mat-row *matRowDef="let row;let i=index; columns: ['secondary'];" [style.display]="elementArr[row.position]===1?'':'none'" [formGroupName]="i">
 </tr>

</table>
</form>
<div *ngIf="isEdited" class="action-btn">
  <button mat-raised-button matTooltip="Add comment" (click)="onCancel()">Cancel</button>
   <button mat-raised-button color="primary" (click)="onEdit()">Save</button>
</div>

table.component.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormArray } from '@angular/forms';

@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol','actions'];
  isEdited:boolean;
  elementArr:any=[].fill(0);
  bankRelationForm: FormGroup;

  dataSource =[
    { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
    { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' },
    { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' },
  ];

  constructor(private fb: FormBuilder) { }

  ngOnInit() {
    this.formInitialize();
    this.setForm();
  }

  formInitialize(){
    this.bankRelationForm = this.fb.group({
      bankRelationData: this.fb.array([])
    });
  }

  setForm(){
    const control = <FormArray>this.bankRelationForm.get('bankRelationData');
    for( const d of this.dataSource){
      const row = this.fb.group({
        position:[d.position? d.position : null],
        name:[d.name? d.name : null],
        weight:[d.weight? d.weight : null],
        symbol:[d.symbol? d.symbol : null],
      });
      control.push(row);
    }
    console.log(control)
  }

  onAdd(i) {
    this.elementArr[i]=1;
  }

  onRemove(i){
    this.elementArr[i]=0;
  }

  onEdit(){
    this.isEdited = true;
  }

  onCancel(){
    this.isEdited = false;
  }

}

Also i have the stcakblitz here

S Haque
  • 31
  • 1

1 Answers1

5

You have to use either dataIndex or renderIndex within row, like below:

<td mat-cell *matCellDef="let element;let i = dataIndex;" [formGroupName]="i">

</td>
  • this worked for me thanks - there is a big difference between dataIndex and renderIndex and you need to use the right one for your scenario. If you are unsure of what values are being produced, then just dump them like this {{ dataIndex }} and make sure its the value you want. I understand the difference, but its hard to explain without confusing someone! – danday74 Jul 26 '21 at 14:55