How to open mat-menu programmatically?

If you want to completely control it programmatically, without having an element on your website that also controls the menu, you can declare an element containing [matMenuTriggerFor], but hiding it via CSS.

Caveat: You will have to manually position the menu. You can do it roughly like that:

Template:

<div #menuTrigger [matMenuTriggerFor]="menu" class="menu-trigger">I will be hidden</div>
<mat-menu #menu class="your-menu-class">
...
</mat-menu>

CSS:

.menu-trigger {
  display: none;
}

Component:

class YourComponent {
  @ViewChild(MatMenuTrigger) menuTrigger: MatMenuTrigger | undefined;

  constructor(private readonly viewRef: ViewContainerRef) { }

  someMethod() {
    this.menuTrigger?.menuOpened.pipe(take(1)).subscribe(() => {
      const menu = document.getElementsByClassName('your-menu-class')[0] as HTMLElement;
      const position: DOMRect = this.viewRef.element.nativeElement.getBoundingClientRect();

      menu.style.position = 'absolute';
      menu.style.top = `${position.top}px`;
      menu.style.left = `${position.width}px`;
    });

    this.menuTrigger?.openMenu();
  }
}

You can also control the <mat-menu> directly in the code. Here is an example:

import { Component, ViewChild } from '@angular/core';
import { MatMenuTrigger } from '@angular/material/menu';

...
export class LanguageComponent {
  @ViewChild('languageMenuTrigger') languageMenuTrigger: MatMenuTrigger;
  
  ...

  openMenu() {
    this.languageMenuTrigger.openMenu();
  }
  
  closeMenu() {
    this.languageMenuTrigger.closeMenu();
  }
}
<button
  mat-button
  [matMenuTriggerFor]="languageMenu"
  #languageMenuTrigger="matMenuTrigger">
  Language
  <mat-icon>expand_more</mat-icon>
</button>
<mat-menu #languageMenu="matMenu">
  <button
    mat-menu-item>
    English
  </button>
  <button
    mat-menu-item>
    Français
  </button>
</mat-menu>

You need to get hold of MatMenuTrigger instance from [matMenuTriggerFor] element

#menuTrigger="matMenuTrigger"  [matMenuTriggerFor]="menu"

where

  • #menuTrigger is the template reference variable

  • matMenuTrigger is exportAs property of MatMenuTrigger metadata

and then simply call

(click)="menuTrigger.openMenu()"

Stackblitz example

Read more about template reference variable here

  • What is #auto attribute here and why it is required