Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material MdSidebar - How to call .toggle() from typescript

I am trying to sidenav toggle from another component, however when the .toggle() function gets called from my parent component it throws this error:

AppComponent.html:1 ERROR TypeError: this.sidenav.toggle is not a function at AppComponent.webpackJsonp.176.AppComponent.toggleNav (app.component.ts:25)

here is the code: app.component.ts

import { Component, ViewChild } from '@angular/core';
import { MaterialModule } from '@angular/material';
import { NavComponent } from './nav/nav.component';
import { SidebarComponent } from './sidebar/sidebar.component';
import { FooterComponent } from './footer/footer.component';
import { MdSidenav } from '@angular/material';
@Component({
    moduleId: module.id,
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent{
    title = 'CRS Management App';
    @ViewChild('sidenav') sidenav:MdSidenav;
    toggleNav(){
      this.sidenav.toggle();
    }
}

app.component.html:

<app-nav #navbar (nav)="toggleNav()"></app-nav>
<app-sidebar #sidenav></app-sidebar>
<app-footer></app-footer>

the (nav) is emitted from the app-nav component.

sidebar.component.ts:

@Component({
  selector: 'app-sidebar',
  templateUrl: './sidebar.component.html',
  styleUrls: ['./sidebar.component.scss']
})
export class SidebarComponent {
    title = 'CRS';

  constructor() { }

}

sidebar.component.html:

 <md-sidenav-container class="container">
<!--SIDEBAR -->
    <md-sidenav #sidebar class="sidebar" mode="over" opened="true">

        <!-- MENU https://material.angular.io/components/component/list -->
         <div class="nav-links">
            <md-nav-list> <!--TODO Links -->
               <a md-list-item href="/one"> Option </a> <!--TODO Icon -->
               <a md-list-item href="/two"> Option </a> <!--TODO Icon-->
               <a md-list-item href="/three"> Option </a> <!--TODO Icon-->
               <span class="flex"></span><!--TODO Divider-->
               <a md-list-item href="/four"> _______ </a> <!--TODO Icon-->
               <a md-list-item href="/five"> Option </a> <!--TODO Icon -->
               <a md-list-item href="/six"> Option </a> <!--TODO Icon-->
               <a md-list-item href="/seven"> Option </a> <!--TODO Icon-->
               <a md-list-item href="/eight"> Option </a> <!--TODO Icon-->
            </md-nav-list>
        <!-- SETTINGS -->
            <!--TODO link to settings -->
            <!--TODO Convert to md-list-item -->
            <button md-button class="md-icon-button" aria-label="Settings">
                Settings<md-icon>settings</md-icon> 
            </button>
        <!-- SETTINGS END -->
        </div>

    </md-sidenav>
<!-- SIDEBAR ENDS -->
<router-outlet></router-outlet>
</md-sidenav-container>

I have tried using AfterViewInit, it throws:

ERROR TypeError: this.sideNav.toggle is not a function at AppComponent.webpackJsonp.176.AppComponent.toggleNav (http://127.0.0.1:4200/main.bundle.js:171:22)

like image 830
Nicholas Foden Avatar asked Apr 24 '17 21:04

Nicholas Foden


1 Answers

The template ref #sidenav on the AppComponent refers to the SidebarComponent which does not have a toggle function.

You could add one to it which then calls the sidenav.toggle() and then you could call that from the AppComponent.

sidebar.component.ts

  import { Component, OnInit, ViewChild } from '@angular/core';
  import { MatSidenav} from '@angular/material';

  @Component({
    selector: 'app-sidebar',
    templateUrl: './sidebar.component.html',
    styleUrls: ['./sidebar.component.css']
  })
  export class SidebarComponent implements OnInit {
    title = 'CRS';
    @ViewChild('sidenav') sidenav: MatSidenav;
    constructor() { }

    ngOnInit() {
    }

    toggle() {
      this.sidenav.toggle();
    }
  }

sidebar.component.html

  <md-sidenav-container class="container">
    <md-sidenav #sidenav class="sidebar" mode="over" opened="true">
    ...

    </md-sidenav>      
 </md-sidenav-container>
like image 146
JayChase Avatar answered Sep 24 '22 20:09

JayChase