angulartypescriptrestangular8angular-material-8

Angular Material - table mat-table not rendering data from rest api


I have been trying to implement mat-table in angular 8. I don't understand what I'm doing wrong, the data which is being provided by my REST endpoint is clearly visible on the console output.

my admin.component.html file

    <table mat-table [dataSource]="dataSource">
        <!-- <ng-container *ngFor="let value of values;let i=index;">
            <tr *ngFor ="let row of {{value.rows}};let i = index;">
                <th mat-header-cell *matHeaderCellDef>{{row.header}}</th>
                <td mat-cell>{{}}</td>
            </tr>
        </ng-container> -->

        <ng-container matColumnDef="position">
                <th mat-header-cell *matHeaderCellDef> No.</th>
                <td mat-cell *matCellDef="let data"> {{data.position}} </td>
              </ng-container>

        <ng-container matColumnDef="USERNAME">
                <th mat-header-cell *matHeaderCellDef> USERNAME</th>
                <td mat-cell *matCellDef="let data"> {{data.username}} </td>
              </ng-container>

              <!-- Name Column -->
              <ng-container matColumnDef="BU">
                <th mat-header-cell *matHeaderCellDef> BU</th>
                <td mat-cell *matCellDef="let data"> {{data.BU}} </td>
              </ng-container>

              <!-- Weight Column -->
              <ng-container matColumnDef="DURATION">
                <th mat-header-cell *matHeaderCellDef> DURATION </th>
                <td mat-cell *matCellDef="let data"> {{data.duration}} </td>
              </ng-container>

              <!-- Symbol Column -->
              <ng-container matColumnDef="PURPOSE">
                <th mat-header-cell *matHeaderCellDef> PURPOSE</th>
                <td mat-cell *matCellDef="let data"> {{data.remarks}} </td>
              </ng-container>
              <ng-container matColumnDef="apr">
                    <th mat-header-cell *matHeaderCellDef>
                         <mat-checkbox (change)="$event ? masterToggle() : null"
                                        [checked]="selection.hasValue() && isAllSelected()"
                                        [indeterminate]="selection.hasValue() && !isAllSelected()"
                                        [aria-label]="checkboxLabel()">
                                APPROVE</mat-checkbox></th>
                    <td mat-cell *matCellDef="let row" >
                            <mat-checkbox (click)="$event.stopPropagation()"
                                          (change)="$event ? selection.toggle(row) : null"
                                            [checked]="selection.isSelected(row)"
                                            [aria-label]="checkboxLabel(row)">Approve</mat-checkbox>
                    </td>
                  </ng-container>

                  <ng-container matColumnDef="rej">
                        <th mat-header-cell *matHeaderCellDef> REJECT</th>
                        <td mat-cell *matCellDef="let row" >
                                <mat-checkbox >Reject</mat-checkbox>
                        </td>
                      </ng-container>

              <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
              <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
              <!-- <tr mat-footer-row *matFooterRowDef><button mat-button> Submit</button></tr> -->
            </table>
            <button mat-button color="primary" (click)="OnApprovalSubmit()">Submit</button>


my ts file

export interface UserData{
  position:number;
  username:any;
  BU:any;
  duration:any;
  remarks:string;

}

@Component({
  selector: 'app-admin',
  templateUrl: 'admin.component.html',
  styleUrls: ['./app.component.css']
})

export class AdminComponent implements OnInit{
  displayedColumns: string[] = ['position','USERNAME', 'BU', 'DURATION', 'PURPOSE','apr','rej'];
  USER_DATA:any;

  // approve:any;
  // reject:any;

  constructor(public testService : TestService){}
  ngOnInit(){
    this.testService.getUserAccessDetails().subscribe(data =>{
      console.log(data);
      this.USER_DATA=data.USER_DATA;
      console.log(this.USER_DATA);

    })

  }


  dataSource = new MatTableDataSource<UserData>(this.USER_DATA);
  // console.log(this.USER_DATA);
  selection = new SelectionModel<UserData>(true, []);

  isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
  }

  /** Selects all rows if they are not all selected; otherwise clear selection. */
  masterToggle() {
    console.log(this.USER_DATA);
    this.isAllSelected() ?
        this.selection.clear() :
        this.dataSource.data.forEach(row => this.selection.select(row));
  }

  /** The label for the checkbox on the passed row */
  checkboxLabel(row?: UserData): string {
    if (!row) {
      return `${this.isAllSelected() ? 'select' : 'deselect'} all`;
    }
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
  }

}

when the console data it is coming in this format

USER_DATA: Array(1)
0: {position: "01", username: "NAme", BU: "Team", Duration: 3, remarks: "NA"}

but still no rows are getting rendered and there is no error also. Any help on this would be appreciated.


Solution

  • You need to provide the result obtained as 'dataSource' inside the subscribe, since it is the dataSource provided as an input to the mat-table.

    ngOnInit() {
        this.testService.getUserAccessDetails()
        .subscribe(data => {
             this.USER_DATA=data.USER_DATA;
             this.dataSource = new MatTableDataSource<UserData>(this.USER_DATA);
        });
    }