Blue Moon
Blue Moon

Reputation: 449

What is the differences between these two kind of angular data tables?

I intended to design a dynamic angular data table. so I defined an array named as displayedColumns and filled it with column names. Then I filled dataSource with proper data and everything gets ready to start.

First I tested static column names and everything works great.

Then I tried to make data table dynamic. I used displayedColumns as column name array instead of position column for testing and everything was OK again and I received the same result as the first code produced.

But confusing arises when I decided to replace all of the other columns with their array and index and when I did it, it gave an error!

Here is my first code:

    <table mat-table [dataSource]="this.dataSource">
  <!-- Position Column -->
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef> No. </th>
    <td mat-cell *matCellDef="let element"> {{element.position}} </td>
  </ng-container>

  <!-- BrandTitle Column -->
  <ng-container matColumnDef="brandTitle">
    <th mat-header-cell *matHeaderCellDef> BrandTitle </th>
    <td mat-cell *matCellDef="let element"> {{element.brandTitle}} </td>
  </ng-container>

  <!-- BrandURL Column -->
  <ng-container matColumnDef="brandURL">
    <th mat-header-cell *matHeaderCellDef> BrandURL </th>
    <td mat-cell *matCellDef="let element"> {{element.brandURL}} </td>
  </ng-container>

  <!-- BrandDescription Column -->
  <ng-container matColumnDef="brandDescription">
    <th mat-header-cell *matHeaderCellDef> BrandDescription </th>
    <td mat-cell *matCellDef="let element"> {{element.brandDescription}} </td>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

second code is :

<table mat-table [dataSource]="this.dataSource">
  <!-- Position Column -->
  <ng-container [matColumnDef]="displayedColumns[0]">
    <th mat-header-cell *matHeaderCellDef> {{displayedColumns[0]}} </th>
     <td mat-cell *matCellDef="let element"> {{element[displayedColumns[0]]}} </td>
  </ng-container>

  <!-- BrandTitle Column -->
  <ng-container matColumnDef="brandTitle">
    <th mat-header-cell *matHeaderCellDef> BrandTitle </th>
    <td mat-cell *matCellDef="let element"> {{element.brandTitle}} </td>
  </ng-container>

  <!-- BrandURL Column -->
  <ng-container matColumnDef="brandURL">
    <th mat-header-cell *matHeaderCellDef> BrandURL </th>
    <td mat-cell *matCellDef="let element"> {{element.brandURL}} </td>
  </ng-container>

  <!-- BrandDescription Column -->
  <ng-container matColumnDef="brandDescription">
    <th mat-header-cell *matHeaderCellDef> BrandDescription </th>
    <td mat-cell *matCellDef="let element"> {{element.brandDescription}} 
</td>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

finally 3rd code is:

        <table mat-table [dataSource]="this.dataSource">
      <!-- Position Column -->
      <ng-container [matColumnDef]="displayedColumns[0]">
        <th mat-header-cell *matHeaderCellDef> {{displayedColumns[0]}} </th>
         <td mat-cell *matCellDef="let element"> {{element[displayedColumns[0]]}} </td>
      </ng-container>

      <!-- BrandTitle Column -->
      <ng-container [matColumnDef]="displayedColumns[1]">
        <th mat-header-cell *matHeaderCellDef> {{displayedColumns[1]}} </th>
         <td mat-cell *matCellDef="let element"> {{element[displayedColumns[1]]}} </td>
      </ng-container>

      <!-- BrandURL Column -->
      <ng-container [matColumnDef]="displayedColumns[2]">
        <th mat-header-cell *matHeaderCellDef> {{displayedColumns[2]}} </th>
         <td mat-cell *matCellDef="let element"> {{element[displayedColumns[2]]}} </td>
      </ng-container>

      <!-- BrandDescription Column -->
      <ng-container [matColumnDef]="displayedColumns[3]">
        <th mat-header-cell *matHeaderCellDef> {{displayedColumns[3]}} </th>
         <td mat-cell *matCellDef="let element"> {{element[displayedColumns[3]]}} </td>
      </ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

And error is : Error: Duplicate column definition name provided: "undefined".

Can anyone explain me what's going wrong? and why 2nd code works and 3rd not?

I need to let you know that this code executed successfully:

<table mat-table [dataSource]="this.dataSource">
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef> {{displayedColumns[0]}} </th>
    <td mat-cell *matCellDef="let element"> {{element[displayedColumns[0]]}} </td>
  </ng-container>

  <!-- BrandTitle Column -->
  <ng-container matColumnDef="brandTitle">
    <th mat-header-cell *matHeaderCellDef> {{displayedColumns[1]}}// </th>
    <td mat-cell *matCellDef="let element"> {{element[displayedColumns[1]]}} </td>
  </ng-container>

  <!-- BrandURL Column -->
  <ng-container matColumnDef="brandURL">
    <th mat-header-cell *matHeaderCellDef> {{displayedColumns[2]}}// </th>
    <td mat-cell *matCellDef="let element"> {{element[displayedColumns[2]]}} </td>
  </ng-container>

  <!-- BrandDescription Column -->
  <ng-container matColumnDef="brandDescription">
    <th mat-header-cell *matHeaderCellDef> {{displayedColumns[3]}}// </th>
    <td mat-cell *matCellDef="let element"> {{element[displayedColumns[3]]}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

The problem is with matColumnDef.

You may want to know that if I use [matColumnDef]="displayedColumns[x]" in just one column is OK and works fine but when I use it in another column it raises error!

any Idea?

Upvotes: 1

Views: 3170

Answers (1)

Blue Moon
Blue Moon

Reputation: 449

The solution is :

<table mat-table [dataSource]="this.dataSource">
  <div *ngFor="let displayedColumn of displayedColumns">
    <ng-container [matColumnDef]="displayedColumn">
        <th mat-header-cell *matHeaderCellDef> {{displayedColumn}} </th>
        <td mat-cell *matCellDef="let element"> {{element[displayedColumn]}} </td>
    </ng-container>
  </div>
  <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

Upvotes: 2

Related Questions