title: Use a variable to specify the mat-menu element to [matMenuTriggerFor]?
body: <p>I am an Angular newbie attempting to implement a table-driven cascading menu using Material 2 but get run-time errors when I try to use a variable to assign the value of the mat-menu element name to [matMenuTriggerFor]. All the examples I have been able to find use text strings to specify the mat-menu element name; I have been unable to locate posts anywhere on the web indicating that anyone else is experiencing a similar problem though I did find a months-old post on github reporting as a bug that binding to [matMenuTriggerFor] didn't work but it had been closed as a Material version 4.x.x-related problem. It appears that [matMenuTriggerFor] is expecting the value of an expression but my attempt doesn't work. What am I doing wrong?</p>
  
  <p>I am on Win 10 and my browser is Firefox 57.0.2</p>
  
  <p>My Angular versions:</p>
  
  <pre><code>Angular CLI: 1.5.0
  Node: 6.11.3
  OS: win32 x64
  Angular: 5.1.2
  ... animations, common, compiler, compiler-cli, core, forms
  ... http, language-service, platform-browser
  ... platform-browser-dynamic, router
  
  @angular/cdk: 5.0.2
  @angular/cli: 1.5.0
  @angular/material: 5.0.2
  @angular-devkit/build-optimizer: 0.0.36
  @angular-devkit/core: 0.0.22
  @angular-devkit/schematics: 0.0.42
  @ngtools/json-schema: 1.1.0
  @ngtools/webpack: 1.8.0
  @schematics/angular: 0.1.11
  @schematics/schematics: 0.0.11
  typescript: 2.4.2
  webpack: 3.8.1
  </code></pre>
  
  <p>My app.module.ts:</p>
  
  <pre><code>import { BrowserModule }            from '@angular/platform-browser';
  import { NgModule }                 from '@angular/core';
  import { BrowserAnimationsModule }  from '@angular/platform-browser/animations';
  import { MatMenuModule }            from '@angular/material/menu';
  import { MatToolbarModule }         from '@angular/material/toolbar';
  import { MatIconModule }            from '@angular/material/icon';
  import { MatListModule }            from '@angular/material/list';
  
  
  import { AppComponent }             from './app.component';
  import { NestedMenusComponent }     from './nested-menus/nested-menus.component';
  
  @NgModule({
    declarations: [
      AppComponent,
      NestedMenusComponent
    ],
    imports: [
      BrowserModule,
      BrowserAnimationsModule,
      MatMenuModule,
      MatToolbarModule,
      MatIconModule,
      MatListModule,
    ],
    providers: [],
    bootstrap: [AppComponent]
  })
  export class AppModule { }
  </code></pre>
  
  <p>My component.ts:</p>
  
  <pre><code>import { Component, OnInit } from '@angular/core';
  
  @Component({
    selector: 'app-nested-menus',
    templateUrl: './nested-menus.component.html',
    styleUrls: ['./nested-menus.component.scss']
  })
  export class NestedMenusComponent implements OnInit {
  
    constructor() { }
  
    ngOnInit() { }
  
    selected :string;
    menuItems = [
      {text: "Tabledriven.Item1" },
      {text: "Tabledriven.Item2", templateName: "submenu"},
    ];
  
    select(pText :string)
    {
      this.selected = pText;
    }
  }
  </code></pre>
  
  <p>My component.html:</p>
  
  <pre><code>&lt;div&gt;
    &lt;p&gt;You selected: {{ selected }}&lt;/p&gt;
  
    &lt;div class="demo-menu"&gt;
      &lt;div class="menu-section"&gt;
        &lt;p&gt;Basic Menu&lt;/p&gt;
        &lt;mat-toolbar&gt;
          &lt;button mat-icon-button [matMenuTriggerFor]="basic"&gt;
            &lt;mat-icon&gt;more_vert&lt;/mat-icon&gt;
          &lt;/button&gt;
        &lt;/mat-toolbar&gt;
  
        &lt;mat-menu #basic="matMenu"&gt;
          &lt;button mat-menu-item  (click)="select('Basic.Item1')"&gt;Basic.Item1&lt;/button&gt;
          &lt;button mat-menu-item [matMenuTriggerFor]="submenu"&gt;Basic.Item2&lt;/button&gt;
        &lt;/mat-menu&gt;
      &lt;/div&gt;
  
      &lt;div class="menu-section"&gt;
        &lt;p&gt;Table-driven Menu&lt;/p&gt;
        &lt;mat-toolbar&gt;
          &lt;button mat-icon-button [matMenuTriggerFor]="tabledriven"&gt;
            &lt;mat-icon&gt;more_vert&lt;/mat-icon&gt;
          &lt;/button&gt;
        &lt;/mat-toolbar&gt;
  
        &lt;mat-menu #tabledriven="matMenu"&gt;
          &lt;ng-container *ngFor="let item of menuItems"&gt;
            &lt;button *ngIf=!item.templateName mat-menu-item (click)="select(item.text)"&gt;{{ item.text }}&lt;/button&gt;
            &lt;button *ngIf=item.templateName  mat-menu-item [matMenuTriggerFor]=item.templateName&gt;{{ item.text }}&lt;/button&gt;
          &lt;/ng-container&gt;
        &lt;/mat-menu&gt;
      &lt;/div&gt;
  
      &lt;mat-menu #submenu="matMenu"&gt;
        &lt;button mat-menu-item (click)="select('Submenu.Item1')"&gt;Submenu.Item1&lt;/button&gt;
        &lt;button mat-menu-item (click)="select('Submenu.Item2')"&gt;Submenu.Item2&lt;/button&gt;
      &lt;/mat-menu&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>The Table-driven menu throws run-time errors before any user input:</p>
  
  <pre><code>ERROR 
  TypeError: this.menu.close is undefined
  Stack trace:
  MatMenuTrigger.prototype.ngAfterContentInit@webpack-internal:///../../../material/esm5/menu.es5.js:771:9
  callProviderLifecycles@webpack-internal:///../../../core/esm5/core.js:12929:9
  callElementProvidersLifecycles@webpack-internal:///../../../core/esm5/core.js:12903:13
  callLifecycleHooksChildrenFirst@webpack-internal:///../../../core/esm5/core.js:12886:29
  checkAndUpdateView@webpack-internal:///../../../core/esm5/core.js:14036:5
  callViewAction@webpack-internal:///../../../core/esm5/core.js:14383:21
  execEmbeddedViewsAction@webpack-internal:///../../../core/esm5/core.js:14341:17
  checkAndUpdateView@webpack-internal:///../../../core/esm5/core.js:14033:5
  callViewAction@webpack-internal:///../../../core/esm5/core.js:14383:21
  execEmbeddedViewsAction@webpack-internal:///../../../core/esm5/core.js:14341:17
  checkAndUpdateView@webpack-internal:///../../../core/esm5/core.js:14033:5
  callViewAction@webpack-internal:///../../../core/esm5/core.js:14383:21
  execComponentViewsAction@webpack-internal:///../../../core/esm5/core.js:14315:13
  checkAndUpdateView@webpack-internal:///../../../core/esm5/core.js:14038:5
  callViewAction@webpack-internal:///../../../core/esm5/core.js:14383:21
  execComponentViewsAction@webpack-internal:///../../../core/esm5/core.js:14315:13
  checkAndUpdateView@webpack-internal:///../../../core/esm5/core.js:14038:5
  callWithDebugContext@webpack-internal:///../../../core/esm5/core.js:15286:39
  debugCheckAndUpdateView@webpack-internal:///../../../core/esm5/core.js:14823:12
  ViewRef_.prototype.detectChanges@webpack-internal:///../../../core/esm5/core.js:11797:13
  ApplicationRef.prototype.tick/&lt;@webpack-internal:///../../../core/esm5/core.js:6104:58
  ApplicationRef.prototype.tick@webpack-internal:///../../../core/esm5/core.js:6104:13
  ApplicationRef.prototype._loadComponent@webpack-internal:///../../../core/esm5/core.js:6170:9
  ApplicationRef.prototype.bootstrap@webpack-internal:///../../../core/esm5/core.js:6058:9
  PlatformRef.prototype._moduleDoBootstrap/&lt;@webpack-internal:///../../../core/esm5/core.js:5778:74
  PlatformRef.prototype._moduleDoBootstrap@webpack-internal:///../../../core/esm5/core.js:5778:13
  PlatformRef.prototype.bootstrapModuleFactory/&lt;/&lt;/&lt;@webpack-internal:///../../../core/esm5/core.js:5699:21
  ZoneDelegate.prototype.invoke@webpack-internal:///../../../../zone.js/dist/zone.js:392:17
  onInvoke@webpack-internal:///../../../core/esm5/core.js:4949:24
  ZoneDelegate.prototype.invoke@webpack-internal:///../../../../zone.js/dist/zone.js:391:17
  Zone.prototype.run@webpack-internal:///../../../../zone.js/dist/zone.js:142:24
  scheduleResolveOrReject/&lt;@webpack-internal:///../../../../zone.js/dist/zone.js:873:52
  ZoneDelegate.prototype.invokeTask@webpack-internal:///../../../../zone.js/dist/zone.js:425:17
  onInvokeTask@webpack-internal:///../../../core/esm5/core.js:4940:24
  ZoneDelegate.prototype.invokeTask@webpack-internal:///../../../../zone.js/dist/zone.js:424:17
  Zone.prototype.runTask@webpack-internal:///../../../../zone.js/dist/zone.js:192:28
  drainMicroTaskQueue@webpack-internal:///../../../../zone.js/dist/zone.js:602:25
  NestedMenusComponent.html:29:10
  View_NestedMenusComponent_3
  NestedMenusComponent.html:29:10
  DebugContext_.prototype.logError
  core.js:15030
  ErrorHandler.prototype.handleError
  core.js:1488
  ApplicationRef.prototype.tick/&lt;
  core.js:5915:54
  ZoneDelegate.prototype.invoke
  zone.js:392
  Zone.prototype.run
  zone.js:142
  NgZone.prototype.runOutsideAngular
  core.js:4701:47
  ApplicationRef.prototype.tick
  core.js:5915
  ApplicationRef.prototype._loadComponent
  core.js:5974
  ApplicationRef.prototype.bootstrap
  core.js:5862
  PlatformRef.prototype._moduleDoBootstrap/&lt;
  core.js:5582:65
  PlatformRef.prototype._moduleDoBootstrap
  core.js:5582
  PlatformRef.prototype.bootstrapModuleFactory/&lt;/&lt;/&lt;
  core.js:5503
  ZoneDelegate.prototype.invoke
  zone.js:392
  onInvoke
  core.js:4753
  ZoneDelegate.prototype.invoke
  zone.js:391
  Zone.prototype.run
  zone.js:142
  scheduleResolveOrReject/&lt;
  zone.js:873
  ZoneDelegate.prototype.invokeTask
  zone.js:425
  onInvokeTask
  core.js:4744
  ZoneDelegate.prototype.invokeTask
  zone.js:424
  Zone.prototype.runTask
  zone.js:192
  drainMicroTaskQueue
  zone.js:602
  ERROR CONTEXT 
  Object { view: {…}, nodeIndex: 2, nodeDef: {…}, elDef: {…}, elView: {…} }
  NestedMenusComponent.html:29:10
  Angular is running in the development mode. Call enableProdMode() to enable the production mode.
  core.js:3660
  [WDS] Disconnected!
  client:164
  </code></pre>
  
  <p>The Basic menu works as desired. When the Table-driven menu is opened, the menu's two items are displayed and the second item contains the icon indicating that it exposes a  sub-menu but the following run-time error is thrown:</p>
  
  <pre><code>ERROR 
  TypeError: templateRef is undefined
   Stack trace:
  ViewContainerRef_.prototype.createEmbeddedView@webpack-internal:///../../../core/esm5/core.js:11626:30
  DomPortalOutlet.prototype.attachTemplatePortal@webpack-internal:///../../../cdk/esm5/portal.es5.js:448:40
  BasePortalOutlet.prototype.attach@webpack-internal:///../../../cdk/esm5/portal.es5.js:303:20
  OverlayRef.prototype.attach@webpack-internal:///../../../cdk/esm5/overlay.es5.js:647:45
  MatMenuTrigger.prototype.openMenu@webpack-internal:///../../../material/esm5/menu.es5.js:861:13
  MatMenuTrigger.prototype._handleClick@webpack-internal:///../../../material/esm5/menu.es5.js:1185:13
  View_NestedMenusComponent_3/&lt;@ng:///AppModule/NestedMenusComponent.ngfactory.js:64:23
  handleEvent@webpack-internal:///../../../core/esm5/core.js:13777:115
  callWithDebugContext@webpack-internal:///../../../core/esm5/core.js:15286:39
  debugHandleEvent@webpack-internal:///../../../core/esm5/core.js:14873:12
  dispatchEvent@webpack-internal:///../../../core/esm5/core.js:10186:16
  renderEventHandlerClosure/&lt;@webpack-internal:///../../../core/esm5/core.js:10807:38
  decoratePreventDefault/&lt;@webpack-internal:///../../../platform-browser/esm5/platform-browser.js:2679:53
  ZoneDelegate.prototype.invokeTask@webpack-internal:///../../../../zone.js/dist/zone.js:425:17
  onInvokeTask@webpack-internal:///../../../core/esm5/core.js:4940:24
  ZoneDelegate.prototype.invokeTask@webpack-internal:///../../../../zone.js/dist/zone.js:424:17
  Zone.prototype.runTask@webpack-internal:///../../../../zone.js/dist/zone.js:192:28
  ZoneTask.invokeTask@webpack-internal:///../../../../zone.js/dist/zone.js:499:24
  invokeTask@webpack-internal:///../../../../zone.js/dist/zone.js:1540:9
  globalZoneAwareCallback@webpack-internal:///../../../../zone.js/dist/zone.js:1566:17
  NestedMenusComponent.html:29:10
  ERROR CONTEXT 
  Object { view: {…}, nodeIndex: 0, nodeDef: {…}, elDef: {…}, elView: {…} }
  NestedMenusComponent.html:29:10
  </code></pre>