title: Delete Selected Rows on Looped Rows on Angular Material Data Table (Angular 7)
body: <p>I have a dynamic data table build using Angular Material where I am using an API to supply the table with data currently.</p>
  
  <p>What I am trying to do is add delete capability where I am able to select a row and delete the entire row.</p>
  
  <p>I want to use mat-checkbox to select the the row, and use a delete button in the header to delete the selected row.</p>
  
  <p>Right now, the checkbox are added on every cell item in the row, where I would rather to select the entire row.</p>
  
  <p>How can/could I add or fix this funtionality?</p>
  
  <p><strong>HTML Component</strong> </p>
  
  <pre><code> &lt;mat-card *ngIf="!loading"&gt;
  &lt;span&gt;
      &lt;mat-card-header class="mat-card-header view-title" style="background-color: lightblue;
      padding: 11px 0px 0px 0px;
      margin: 0px 0px 8px 0px;
      box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 15px 0 rgba(0, 0, 0, 0.19)"&gt;
      &lt;mat-card-title&gt;{{viewName}}&lt;/mat-card-title&gt;
      &lt;span class="fill-nav-bar"&gt;&lt;/span&gt;
        &lt;button style="padding-right: 80px;" mat-icon-button&gt;
          &lt;mat-icon&gt;cancel&lt;/mat-icon&gt;
        &lt;/button&gt;
        &lt;/mat-card-header&gt;
  &lt;/span&gt;
  
    &lt;mat-card-content&gt;
      &lt;div class="view-container mat-elevation-z8"&gt;
        &lt;table mat-table [dataSource]="dataSource" matSort&gt;
  
          &lt;ng-container [matColumnDef]="column" *ngFor="let column of displayedColumns"&gt;
            &lt;th mat-header-cell *matHeaderCellDef mat-sort-header&gt;
              {{ column }}
              &lt;mat-icon aria-hidden="false" aria-label="filter icon"&gt;more_horiz&lt;/mat-icon&gt;
            &lt;/th&gt;
            &lt;td mat-cell *matCellDef="let action"&gt;{{ action[column] }}
             &lt;mat-checkbox&gt;&lt;/mat-checkbox&gt;
            &lt;/td&gt;
          &lt;/ng-container&gt;
  
          &lt;tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"&gt;&lt;/tr&gt;
          &lt;tr mat-row *matRowDef="let row; columns: displayedColumns"&gt;&lt;/tr&gt;
        &lt;/table&gt;
  
        &lt;mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons&gt;&lt;/mat-paginator&gt;
      &lt;/div&gt;
    &lt;/mat-card-content&gt;
  &lt;/mat-card&gt;
  </code></pre>
  
  <p><strong>TS Component</strong></p>
  
  <pre><code>@Component({
    templateUrl: 'view.component.html',
    encapsulation: ViewEncapsulation.None
  })
  export class ViewComponent implements OnInit, OnDestroy {
  
    // User Fields
    currentUser: User;
    users: User[] = [];
    currentUserSubscription: Subscription;
  
    loading : boolean;
    // Action Fields
    viewData: any;
    viewName: string;
    refNumber: number;
    currentActionSubscription: Subscription;
    displayedColumns: string[] = [];
    dataSource: any = new MatTableDataSource([]);
    pageSizeOptions: number[] = [10, 20, 50];
  
    @ViewChild(MatSort) sort: MatSort;
    @ViewChild(MatPaginator) paginator: MatPaginator;
  
    defaultSort: MatSortable = {
      id: 'defColumnName',
      start: 'asc',
      disableClear: true
    };
  
    defaultPaginator: MatPaginator;
  
    constructor(
      private iconRegistry: MatIconRegistry,
      private sanitizer: DomSanitizer,
      private actionService: ActionService
    ) {
      this.loading = false;
      this.iconRegistry.addSvgIcon(
        'thumbs-up',
        this.sanitizer.bypassSecurityTrustResourceUrl(
          'assets/img/examples/thumbup-icon.svg'
        )
      );
    }
  
    loadAction(action: any) {
  
      this.loading = true;
      // If there is already data loaded into the View, cache it in the service.
      if (this.viewData) {
        this.cacheAction();
      }
  
      if (this.sort) {
        // If there is sorting cached, load it into the View.
        if (action.sortable) {
          // If the action was cached, we should hit this block.
          this.sort.sort(action.sortable);
        } else {
          // Else apply the defaultSort.
          this.sort.sort(this.defaultSort);
        }
      }
  
      if (this.paginator) {
        // If we've stored a pageIndex and/or pageSize, retrieve accordingly.
        if (action.pageIndex) {
          this.paginator.pageIndex = action.pageIndex;
        } else { // Apply default pageIndex.
          this.paginator.pageIndex = 0;
        }
  
        if (action.pageSize) {
          this.paginator.pageSize = action.pageSize;
        } else { // Apply default pageSize.
          this.paginator.pageSize = 10;
        }
      }
  
      // Apply the sort &amp; paginator to the View data.
      setTimeout(() =&gt; this.dataSource.sort = this.sort, 4000);
      setTimeout(() =&gt; this.dataSource.paginator = this.paginator, 4000);
  
      // Load the new action's data into the View:
      this.viewData = action.action;
      this.viewName = action.action.ActionName;
      this.refNumber = action.refNumber;
  
      // TODO: add uniquifiers/ids and use these as the sort for table
  
      const displayedColumns = this.viewData.Columns.map((c: { Name: any; }) =&gt; c.Name);
      displayedColumns[2] = 'Folder1';
      this.displayedColumns = displayedColumns;
      // tslint:disable-next-line: max-line-length
      const fetchedData = this.viewData.DataRows.map((r: { slice: (arg0: number, arg1: number) =&gt; { forEach: (arg0: (d: any, i: string | number) =&gt; any) =&gt; void; }; }) =&gt; {
        const row = {};
        r.slice(0, 9).forEach((d: any, i: string | number) =&gt; (row[this.displayedColumns[i]] = d));
        return row;
      });
  
      this.dataSource = new MatTableDataSource(fetchedData);
      this.loading = false;
    }
  
  
    // Stores the current Action, sort, and paginator in an ActionState object to be held in the action service's stateMap.
    cacheAction() {
      let actionState = new ActionState(this.viewData);
  
      // Determine the sort direction to store.
      let cachedStart: SortDirection;
      if (this.sort.direction == "desc") {
        cachedStart = 'desc';
      } else {
        cachedStart = 'asc';
      }
  
      // Create a Sortable so that we can re-apply this sort.
      actionState.sortable = {
        id: this.sort.active,
        start: cachedStart,
        disableClear: this.sort.disableClear
      }
  
      // Store the current pageIndex and pageSize.
      actionState.pageIndex = this.paginator.pageIndex;
      actionState.pageSize = this.paginator.pageSize;
  
      // Store the refNumber in the actionState for later retrieval.
      actionState.refNumber = this.refNumber;
      this.actionService.cacheAction(actionState);
    }
  
    ngOnInit() {
      // Subscribes to the action service's currentAction, populating this component with View data.
      this.actionService.currentAction.subscribe(action =&gt; this.loadAction(action));
    }
  </code></pre>