I am using a matMenu in an Angular project which is populated dynamically from an array. This menu can have one level of sub-menu's. My menu definition array looks like this:
{
text: string,
subMenuName: string,
subMenuItems: [{
text: string,
onClick(): void
}]
}
I am trying to build this menu in HTML as follows:
<mat-menu #menu="matMenu">
<button *ngFor="let item of menuItems" [matMenuTriggerFor]="menuItem.subMenuName" mat-menu-item>
{{ item.text }}
</button>
</mat-menu>
<ng-container *ngFor="item of menuItems">
<mat-menu #item.subMenuName="matMenu">
<button *ngFor="let subItem of item.subMenuItems (click)="subItem.onClick();">
{{ subItem.text }}
</button>
</mat-menu>
</ng-container>
When I try to run this, it is not compliing and it is giving the following error:
ERROR TypeError: Cannot read property 'subscribe' of undefined
at MatMenuTrigger.push../node_modules/@angular/material/esm5/menu.es5.js.MatMenuTrigger.ngAfterContentInit
Solution was to create a component which referenced itself recursively. Code below:
TS
HTML
Where
NavItem
is an interface:Then I simply need to reference
<app-menu-item [items]="..">
in my HTML.