3

How to call angular material sidenav actions in component? I have use case that sidenav only can open / close when callMethods() method triggered. I can't simply pass open(e) in callMethods() as well (required 1 arugument). Is there anyway to achieve this?

app.html

<mat-sidenav-container class="example-container">
  <mat-sidenav #sidenav [mode]="mode.value">
    <p>
      some nav here
    </p>
  </mat-sidenav>

  <mat-sidenav-content>
    <p><button mat-button (click)="open(sidenav)">Toggle</button></p>
    <p>
      some text here
    </p>
  </mat-sidenav-content>
</mat-sidenav-container>

app.ts

open(e: any) {
    e.toggle();
  }

  callMethods() {
    this.open(); // required 1 arguments
    this.otherMethod();
  }
anotherMethod() {
    this.open(); // required 1 arguments
    this.otherMethod();
  }

Note: I noticed there is a post but not clear

Jnr
  • 1,504
  • 2
  • 21
  • 36
SKL
  • 1,243
  • 4
  • 32
  • 53
  • Why you just don't replace `(click)="open(sidenav)"`by `(click)="callMethods(sidenav)"`. You can define also `callMethods(e: any`) pass an argument, which is passed also to `this.open(e: any)`. – mpro Nov 14 '19 at 08:24
  • good point but I have to use `open(e)` in few places – SKL Nov 14 '19 at 08:30

4 Answers4

7

A nice clean way of opening and closing the angular material side-nav goes through the [opened] parameter on the component. You can pass it a boolean that you can manipulate to open/close the side-nav.

app.html

<mat-sidenav-container class="example-container">
  <mat-sidenav #sidenav [mode]="mode.value" [opened]="isShowing">
    <p>
      some nav here
    </p>
  </mat-sidenav>

  <mat-sidenav-content>
    <p><button mat-button (click)="toggleSidenav()">Toggle</button></p>
    <p>
      some text here
    </p>
  </mat-sidenav-content>
</mat-sidenav-container>

Your callMethods functions can then cleanly call your toggle method if it's implemented as follows:

app.ts

isShowing: boolean;

toggleSidenav() {
   this.isShowing = !this.isShowing;
}

callMethods() {
    this.toggleSidenav();
}

 
Rutger van Dijk
  • 330
  • 1
  • 9
  • 1
    I think it should be `this.isShowing = !this.sShowing;` under the method: `toggleSidenav()`. – Pramesh Bajracharya Nov 26 '20 at 05:24
  • This is nice but seems to mess up if the toggle button are in 2 diff component. Might need to use a service for this? – ScipioAfricanus Dec 21 '20 at 22:12
  • If they are in two different components there is indeed other solutions necessary. An injectable service could indeed be one of them, but an event-based structure could also be elegant. However, this example shows the base simple example best :) – Rutger van Dijk Dec 23 '20 at 00:53
2

Without much details of my code, I coded a custom method directly in the component.ts

To avoid undefined issue I first declared isShowing = false to automatically hide it at the page building but its up to you.

In the component.ts

toggle(): boolean{
    if (!this.isShowing){
        return this.isShowing = true;
    }
    else{
        return this.isShowing = false;
    }
}

In the component.html :

<mat-drawer [opened]="isShowing"></mat-drawer>

This works perfectly and also allows to give parameters to the function toggle() to inject data and so you can custom the nav content with some parameters that depends of your context.

Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
M Matthieu
  • 359
  • 3
  • 10
1

1) import viewChild in your component.

import { ViewChild } from '@angular/core';

2) Get reference of sidenav before constructor of your component

@ViewChild('sidenav') sidenav;

3) open from method

callMethods() {
  this.open(this.sidenav); // required 1 arguments
  this.otherMethod();
}
mpro
  • 14,302
  • 5
  • 28
  • 43
Naseer
  • 184
  • 1
  • 9
1

my way

  1. to use @Output()

     <mat-sidenav #sidenav ></mat-sidenav>
     <app-header (toggleMenuEvent)="sidenav.toggle()"></app-header>
    
  2. and EventEmmiter

     export class HeaderComponent implements OnInit {
    
     @Output() toggleMenuEvent = new EventEmitter<void>();    
    
     constructor() { }
    
     ngOnInit(): void {
     }
    
     public toggleMenu() {
         this.toggleMenuEvent.emit();
     }