Search code examples
angulartypescriptangular-materialangular-ngmodel

Data binding in dynamically generated rows with dropdown


I have a table which dynamically generates rows with details of uploaded files. The rows have a dropdown to select the file type.

I'm currently facing problems with the dynamically generated dropdown. It sets the same value for all dropdown in all rows if I select a value in any one dropdown.

HTML:

<table>
 <thead>
  <tr>
   <th>File Name</th>
   <th>File Type</th>
  </tr>
 </thead>

 <tbody>
  <tr *ngFor="let item of uploader.queue">
   <td>
    {{ item?.file?.name }}
   </td>

   <td>
    <mat-form-field>
      <mat-select  placeholder="Select File Type" [(ngModel)]="selectedType">
        <mat-option *ngFor="let type of Types" [value]="type.type">
          {{type.type}}
        </mat-option>
       </mat-select>
     </mat-form-field>
   </td>
   <td>
    <button (click)="AddPdf(item)">Upload</button>
   </td>
  </tr>
 </tbody>
<table>

TS:

public AddPdf(Filenames: FileItem) {
  this.data = { filename: FileNames.file.name.toString() , LetterName:this.selectedLetterName, LetterType: this.selectedType };
  console.log(this.data.filename, 'File Name');
  console.log(this.data.LetterName, 'Letter Name');
  console.log(this.data.LetterType, 'Letter Type');
}

Now if I add three files, three rows get generated. And if I select the file type for one row, the same is getting reflected for all the rows.

Please help me understand the flaw here!

Any help is appreciated.


Solution

  • I figured the problem. Instead of [(ngModel)], I separated it into two parts as below:

            <mat-form-field>
              <mat-select
                placeholder="Select Letter Name"
                #lettername
                [ngModel]="selectedLetterName"
                (ngModelChange)="onLetterNameSelect($event)"
                [ngModelOptions]="{standalone: true}">
                <mat-option *ngFor="let LetterName of LetterNames" [value]="LetterName.ReportName">
                  {{LetterName.ReportName}}
                </mat-option>
              </mat-select>
            </mat-form-field>
    

    It worked as I expected after the change.