0

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

5
  • Did you inject Dialog to component constructor ? Commented Feb 13, 2020 at 8:38
  • you probably need to inject the dialog in the constructor constructor(public dialog: MatDialog) {} Commented Feb 13, 2020 at 8:39
  • Dialog was injected, i update it. Reason is somewhere else Commented Feb 13, 2020 at 8:40
  • Any other ideas? Commented Feb 13, 2020 at 9:55
  • Can you create a minimal Stackblitz example? Commented Feb 13, 2020 at 10:49

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.