0
votes

I have issue with action in my menu. I using material menu and icons for this project. The wain menu code looks like this:

<mat-menu #rootMenu="matMenu" [overlapTrigger]="false">
  <ng-template matMenuContent let-element="element">
    <div *ngFor='let item of contextMenu' (click)="item.action(element)">
      <button *ngIf='!item.seperator' mat-menu-item [disabled]="item.disabled">
        <mat-icon>
          {{item.icon}}
        </mat-icon>
        <span>
          {{item.name}}
        </span>
      </button>
      <mat-divider *ngIf='item.seperator'></mat-divider>
    </div>
  </ng-template>
</mat-menu>

Now i show you my menu element model:

export class MenuElement {
  id?: string
  name?: string
  tooltip?: string
  icon?: string
  action: (element : any) => void
  disabled?: boolean = true
  seperator?: boolean = false
}

And at the end, part of menu in component ts:

 constructor(public dialog: MatDialog) {      //#1
 ...
 this.contextMenu = 
 ...
 {
        name: 'Rename',
        icon: 'edit',
        action: this.openRenameDialog,
        disabled: true
 },
 ...

And openRenameDialog function:

  openRenameDialog(element: FileElement) {
    let dialogRef = this.dialog.open(RenameDialogComponent);
    dialogRef.afterClosed().subscribe(res => {
      if (res) {
        element.name = res;
        this.elementRenamed.emit(element);
      }
    });
  }

And at the end, this is my error:

core.js:5828 ERROR TypeError: Cannot read property 'open' of undefined at Object.openRenameDialog [as action] (lib-common.js:4857) at FileExplorerComponent_ng_template_8_div_0_Template_div_click_0_listener (lib-common.js:4550) at executeListenerWithErrorHandling (core.js:21593) at wrapListenerIn_markDirtyAndPreventDefault (core.js:21635) at HTMLDivElement. (platform-browser.js:934) at ZoneDelegate.invokeTask (zone-evergreen.js:400) at Object.onInvokeTask (core.js:40744) at ZoneDelegate.invokeTask (zone-evergreen.js:399) at Zone.runTask (zone-evergreen.js:168) at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:481)

Any ideas what i need to do?

Edit 1

Dialog was injected, look #1

1
Did you inject Dialog to component constructor ?Armen Stepanyan
you probably need to inject the dialog in the constructor constructor(public dialog: MatDialog) {}Natrium
Dialog was injected, i update it. Reason is somewhere elsexavn-mpt
Any other ideas?xavn-mpt
Can you create a minimal Stackblitz example?Rajat

1 Answers

1
votes

Try changing the syntax of the "openRenameDialog" method to

openRenameDialog = (element: FileElement) => {
    // etc 
}

This is probably happening because when you assign action: this.openRenameDialog, the binding to this is targeting the context of the method instead of the context of the class (which is where dialog is actually defined).

In older versions of JS you would need to use bind to reference the correct context. However, with the inclusion of "fat arrows" in ES6, this binding is automatically being done for you.