2

I am new to Angular world and I want to make a Dashboard (with SideNav and TopNav) with Angular Material. So, I installed everything and added the Angular Material library via :

ng add @angular/material

I added also the ready to use component for teh sideNav and TopNav and called it "mynav":

ng add @angular/material:nav mynav

when I run "ng serve -o" I got the sideNav and TopNav as wanted, but the HAMBURGER ICON to show and hide the sideNav is missing in the Desktop (or in any other widescreen device) view. See image here: enter image description here. In the mobile (or in any other small screen device) view though, the "Hamburger menu" is visible and working (toggling function: open and hide the SideNav). See image here: enter image description here.

How to get the "Hamburger Icon" appearing in the big screens like laptops or desktops? I know i should edit the breakpoints for that, but how? Here is the generated code in "mynav.component.html" :

<mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport="true"
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="!(isHandset$ | async)">
    <mat-toolbar>Menu</mat-toolbar>
    <mat-nav-list>
      <a mat-list-item href="#">Link 1</a>
      <a mat-list-item href="#">Link 2</a>
      <a mat-list-item href="#">Link 3</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <mat-toolbar color="primary">
      <button
        type="button"
        aria-label="Toggle sidenav"
        mat-icon-button
        (click)="drawer.toggle()"
        *ngIf="isHandset$ | async">
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>
      <span>project1</span>
    </mat-toolbar>
    <!-- Add Content Here -->
  </mat-sidenav-content>
</mat-sidenav-container>
Edric
  • 24,639
  • 13
  • 81
  • 91
anyname
  • 103
  • 1
  • 11
  • 1
    Simple: Your "Toggle sidenav" icon button has an `ngIf` conditional which indicates that the button is shown based on whether the `isHandset$` variable is truthy. The schematic for the sidenav also generates component code for that `isHandset$` variable which uses the Angular CDK's [`BreakpointObserver`](https://material.angular.io/cdk/layout/api#BreakpointObserver). – Edric Jan 13 '20 at 03:16

4 Answers4

1

Reiterating what I've commented on your question:

Simple: Your "Toggle sidenav" icon button has an ngIf conditional which indicates that the button is shown based on whether the isHandset$ variable is truthy. The schematic for the sidenav also generates component code for that isHandset$ variable which uses the Angular CDK's BreakpointObserver.

Looking at the schematic code for the nav schematic, you can see that the isHandset$ variable is defined as follows:

isHandset$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Handset)
    .pipe(
      map(result => result.matches),
      shareReplay()
    );

constructor(private breakpointObserver: BreakpointObserver) {}

What the above code does in a nutshell:

  1. Observes the document for any changes to the window dimensions. (It uses media queries under the hood by adding event listeners and automatically removing the listeners)
  2. The observe method of BreakpointObserver is documented on the API documentation as follows:

    Gets an observable of results for the given queries that will emit new results for any changes in matching of the given queries.

    Returns a stream of matches for the given queries. (Type: Observable<BreakpointState>

  3. BreakpointState is an interface which contains 2 properties:

    • breakpoints: { [key: string]: boolean; } - A key boolean pair for each query provided to the observe method, with its current matched state.
    • matches: boolean - Whether the breakpoint is currently matching.
  4. As such, the stream is piped through a map pipe which maps the result to the matches property.

  5. And as a result, the menu icon button is hidden based on whether the media query is matched.

The full list of predefined breakpoints (including Breakpoints.Handset) are listed in the documentation.

The BreakpointObserver class is also extensively documented under the Layout section on the CDK docs.

Edric
  • 24,639
  • 13
  • 81
  • 91
0

It is very likely you did not import the required modules for it.

You will need to register the mat-icon component, as you currently using it for your menu's hamburger icon. Therefore, you will need to have to import the MatIconModule, which declares the component. Same goes for the MatButtonModule.

On the module that uses the navigation menu, make the following changes:

import { MatButtonModule, MatIconModule } from '@angular/material';    

@NgModule({
  imports: [
    MatButtonModule,
    MatIconModule,
    // other imported modules
  ],
  // others
wentjun
  • 40,384
  • 10
  • 95
  • 107
  • hi, thanks for the quick answer, but these modules are already automatically imported in the file app.componont.ts : – anyname May 12 '19 at 18:11
  • @anyname Hmm.. Shouldn't they be imported in the .module.ts file instead? – wentjun May 12 '19 at 18:31
  • they are in deed imported automatically to app.module.ts as well. But i think, that by default the Hamburger Icon appears only on small devices. it's better then to look for a method to add a toogling button to the desktop view as well – anyname May 12 '19 at 22:49
  • @anyname Ahh, does it show when you toggle the screen size then? If yes, you will need to overwrite the CSS Media Queries! – wentjun May 13 '19 at 01:13
  • i think it's better to let it so, and add a new toggling button to hide the half of sideNav and let icons visible! thanks @wentjun for the support. – anyname May 13 '19 at 17:46
  • @anyname You're welcome! All the best with the project! – wentjun May 13 '19 at 17:53
0

I can see that you asked the question quite a long time ago but I am gonna post anyway. I have a very similar issue where instead of the icon, literally the word "menu" is shown. I copied your code to see if I get the same result, and by elimination, I figured that the below line of code is leading to your icon not showing

    *ngIf="isHandset$ | async">
Mark
  • 19
  • 4
0

Remove below *ngif condition from button tag and menu icon will appear, it worked for me

*ngIf="isHandset$ | async"