locked
Angular Material mat-table mat-cell binding to datasource of objects and propertities RRS feed

  • Question

  • User956626884 posted

    I am trying to figure out how to bind a collection of objects which is assigned to an Angular mat-table datasource. Here is the data structure which I am using to set as the datasource

    myData: myDataViewModel[] = [
      {
        month: 'January',
        names: [ {name: 'name1'}, 
                 {name: 'name2'}, 
                 {name: name3'}, 
                 {name: 'name4'}
        ]
      },
      {
        month: 'Febuary',
        names: [ {name: 'name5'}, 
                 {name: 'name6'}, 
                 {name: name7'}, 
                 {name: 'name8'}
      }
    
    ];
    

    In my typescript code, this.datasource.data = this.myData;

    So myData is a collection of objects. In my html code, I am able to get the month value displayed on the mat-table but I can get the values of names. When I hit f12, I see the error stating cannot read property 'names'

    I looked at this link,Angular 7 Mapping object with array of object to mat table, but it did not help

    Here is my html code so far

      <table mat-table [dataSource]="dataSource" matSort>
    
    
        <ng-container matColumnDef="month">
            <tr mat-header-cell *matHeaderCellDef mat-sort-header></tr>
            <td mat-cell *matCellDef="let myData"> {{myData.month}} </td>
            <tr><hr></tr>
        </ng-container>
    
    
        <ng-template *ngFor="let myData; let displayName of myData.displayNames" >
            <ng-container matColumnDef={{ displayName.name }}>
       <td mat-cell *matCellDef="let srow">{{ displayName.name}}
              </ng-container>
        </ng-template>
    
    
      <tr mat-header-row *matHeaderRowDef="displayedColumns" class="example-first-header-row"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
    </table >
    Monday, May 6, 2019 5:38 PM

All replies

  • User-893317190 posted

    Hi comicrage ,

    From the link you provided , I have change a little and successfully show all the columns.

    Below is my code.

    export interface PeriodicElement {
      ;
     
       names: {name:String}[]
    }
    
    const ELEMENT_DATA: PeriodicElement[] = [
      {, names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
    
    ]},
      {, names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
    
    ]},
      {, names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
    
    ]},
      {,names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
    
    ]},
      {, names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
    
    ]},
      {, names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
    
    ]},
      {, names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'}
    
    ]},
      {, names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
    
    ]},
      {, names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
     
    ]},
      {,names: [ {name: 'name1'}, 
      {name: 'name2'}, 
      {name: 'name3'} 
    
    ]},
    ];
    
    @Component({
      selector: 'app-my-table-component',
      templateUrl: './my-table-component.component.html',
      styleUrls: ['./my-table-component.component.css']
    })
    export class MyTableComponentComponent implements OnInit {
    
      displayedColumns: string[] = ['position','name1','name2','name3'];
    
      dataSource = ELEMENT_DATA;
      constructor() { }
    
      ngOnInit() {
         
      }
    
    }

    My html.

    <div>
       
       <table mat-table [dataSource]="dataSource">
    
        <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= "{{ displayName}}" *ngFor=" let displayName of ['name1','name2','name3'];index as i">
            <th mat-header-cell *matHeaderCellDef> {{ displayName}}</th>
            <td mat-cell *matCellDef="let srow">  {{ srow.names[i].name}}  
          </ng-container>
    
        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
       </table>
       
         
     
    </div>

    Please pay attention  I removed ng-template.

    The result.

    Best regards,

    Ackerly Xu

    Tuesday, May 7, 2019 3:12 AM