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

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

AppComponent.html: 1 ERROR TypeError: this.sidenav.toggle is not a function in 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>

      

(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 tried using AfterViewInit, it throws:

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

+3


source to share


3 answers


The ref #sidenav template in the AppComponent refers to the SidebarComponent, which has no toggle functionality.

You can add one to it, which then calls sidenav.toggle () and then you can call it 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>

      

+5


source


Try using a ngAfterViewInit

callback
, here's a good example .



0


source


In my case, I did not include MatSidenavModule in the list of module components import. This fixed the problem. It looks like some other Material module is importing SidenaveModule indirectly, so we didn't get the usual error when we don't import a module into our component.

0


source







All Articles