0

Consider the following table in my template

    <mat-table #table [dataSource]="dataSource">

  <!--- Note that these columns can be defined in any order.
        The actual rendered columns are set as a property on the row definition" -->

  <!-- ChangeId Column -->
  <ng-container cdkColumnDef="fileName">
    <mat-header-cell *cdkHeaderCellDef mat-sort-header> File </mat-header-cell>
    <mat-cell *cdkCellDef="let row" (click)="downloadFile(row.SerialNumber)"> <a (click)="downloadFile(row.SerialNumber)">{{row.File}}</a> </mat-cell>
  </ng-container>

  <!-- DateSubmitted -->
  <ng-container cdkColumnDef="fileType">
    <mat-header-cell *cdkHeaderCellDef mat-sort-header> File Type </mat-header-cell>
    <mat-cell *cdkCellDef="let row"> {{row.FileType}} </mat-cell>
  </ng-container>

  <!-- ChangeSponsor -->
  <ng-container cdkColumnDef="contentType">
    <mat-header-cell *cdkHeaderCellDef mat-sort-header> Content Type </mat-header-cell>
    <mat-cell *cdkCellDef="let row"> {{row.ContentType}} </mat-cell>
  </ng-container>

  <mat-header-row *cdkHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *cdkRowDef="let row; columns: displayedColumns;">
  </mat-row>
</mat-table>

And the method it's calling in the component class

downloadFile(serialNumber: number): void {
    this.fileService.downloadFile(serialNumber);
  }

In the above table I'm trying to create a (click) event that calls the downloadFile method, which then calls a method in the service class that sends a file to the browser for the user to download. However in none of the attempts above does it work. So I'm definitely missing something.

Can someone let me know what I'm missing that is not letting this work?

Thanks so much in advance for looking into this.

Edit: I was told this is probably important information, but this is a child component.

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
David
  • 573
  • 7
  • 40

3 Answers3

0

Any reason for putting the click event twice?

 <mat-cell *cdkCellDef="let row" (click)="downloadFile(row.SerialNumber)"> <a (click)="downloadFile(row.SerialNumber)">{{row.File}}</a> </mat-cell>

Try to leave it only in the anchor element:

 <mat-cell *cdkCellDef="let row"> <a (click)="downloadFile(row.SerialNumber)">{{row.File}}</a> </mat-cell>
Ido Lev
  • 941
  • 1
  • 7
  • 10
  • Sorry that was me trying to see if it works implemented in different ways. I've figured out since that, because it's a child component within a parent, I need to implement an @Output event emitter and right now I'm working on doing so properly. Will update question and everything in the interim. – David Nov 21 '17 at 14:30
  • Cool. Good luck! – Ido Lev Nov 21 '17 at 14:42
0

I put a couple of buttons in one of my table rows. The edit one is similar to your case.

<ng-container matColumnDef="delete">
        <mat-header-cell *matHeaderCellDef> Delete / Edit </mat-header-cell>
        <mat-cell *matCellDef="let row">
          <button (click)="deleteMember(row.member_id)">Delete</button>
          <button (click)="goToDetailPage(row.member_id)">Edit</button>
        </mat-cell>
      </ng-container>

In the component:

  //  Called when edit button is clicked. Useer sees a data populated
  //    edit form.  Data is downloaded from a db.

  goToDetailPage(memberId) {
    this.router.navigate([
        '/members/editMember',
        memberId]);
  }


  // Called when delete button is clicked.

  public deleteMember(memberId) {
      // Call the confirm dialog component
      this.confirmService.confirm('Confirm Delete', 'This action is final. Gone forever!')
          .switchMap(res => {if (res === true) {
              return this.membersAdminService.deleteMember(memberId);
          }})
          .subscribe(
              result => {
                this.success();
              },
              (err: HttpErrorResponse) => {
                  console.log(err.error);
                  console.log(err.message);
                this.messagesService.openDialog('Error', 'Delete did not happen.');
              }
          );
  }
Preston
  • 3,260
  • 4
  • 37
  • 51
0

Ok, my issue was indeed due to the component being nested in a parent, so in order for a click event to move up to the parent level I needed to emit it via @Output. I did so accordingly.

Child template

<div *ngIf="isDataAvailable">
  <div class="example-container mat-elevation-z8">
    <div class="example-header">
    </div>
    <mat-table #table [dataSource]="dataSource">

      <!--- Note that these columns can be defined in any order.
            The actual rendered columns are set as a property on the row definition" -->

      <!-- ChangeId Column -->
      <ng-container cdkColumnDef="fileName">
        <mat-header-cell *cdkHeaderCellDef mat-sort-header> File </mat-header-cell>
        <mat-cell *cdkCellDef="let row"> {{row.File}} </mat-cell>
      </ng-container>

      <!-- DateSubmitted -->
      <ng-container cdkColumnDef="fileType">
        <mat-header-cell *cdkHeaderCellDef mat-sort-header> File Type </mat-header-cell>
        <mat-cell *cdkCellDef="let row"> {{row.FileType}} </mat-cell>
      </ng-container>

      <!-- ChangeSponsor -->
      <ng-container cdkColumnDef="contentType">
        <mat-header-cell *cdkHeaderCellDef mat-sort-header> Content Type </mat-header-cell>
        <mat-cell *cdkCellDef="let row"> {{row.ContentType}} </mat-cell>
      </ng-container>

      <mat-header-row *cdkHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *cdkRowDef="let row; columns: displayedColumns;" (click)="onClick(row.SerialNumber)">
      </mat-row>
    </mat-table>
  </div>
</div>

Child Component

  @Input() changeId: number;
  @Input() fileType: string;
  @Output() downloadFile: EventEmitter<string> =
  new EventEmitter<string>();

  onClick(serialNumber: string): void {
    this.downloadFile.emit(serialNumber);
}

Calling child template in parent template

<app-file-selector [changeId]="change.ChangeId" [fileType]="'Release Notes'" (downloadFile)='(downloadFile($event))'></app-file-selector>

The downloadFiles method now located in parent component, and service method moved to parent service class. Method in component below.

downloadFile(serialNumber: string): void {
    this.changeService.downloadFile(serialNumber);
  }
David
  • 573
  • 7
  • 40