I'm interested in changing the md-sidenav - from Angular Material 2 - mode from side (for desktops) to over (mobile). Is there a way to change it programmatically?
Thanks
To set up a sidenav we use three components: <mat-sidenav-container> which acts as a structural container for our content and sidenav, <mat-sidenav-content> which represents the main content, and <mat-sidenav> which represents the added side content.
From the docs: A mat-sidenav can be opened or closed using the open(), close() and toggle() methods. Each of these methods returns a Promise that will be resolved with true when the sidenav finishes opening or false when it finishes closing.
Building on Steve G's solution you could update app.component.html
<md-sidenav [mode]="isLargeScreen() ? 'side' : 'over'" [opened]="isLargeScreen()"></md-sidenav>
And then in app.component.ts
isLargeScreen() {
  const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  if (width > 720) {
      return true;
  } else {
      return false;
  }
}
This gives you a sidebar on desktop opened by default, and on mobile it overlays but is hidden by default!
I found the solution by ObservableMedia.
Component:
import {Component, OnInit, ViewEncapsulation} from "@angular/core";
import {ObservableMedia} from "@angular/flex-layout";
@Component({
  moduleId: module.id,
  selector: 'app-sidebar',
  templateUrl: './sidebar.component.html',
  styleUrls: ['./sidebar.component.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class SidebarComponent implements OnInit {
  constructor(public media:ObservableMedia ) {
  }
  ngOnInit(): void {
  }
}
template:
<md-sidenav-container>
    <md-sidenav #sidenav  mode="{{media.isActive('gt-sm') ? 'side' : 'over'}}" align="begin" class="md-whiteframe-4dp" opened >
      <md-nav-list>
        ...
      </md-nav-list>
    </md-sidenav>
</md-sidenav-container>
Sure! You could do your screen width test (or browser detection, blech) in your component on initialization and store the result in a variable as a string.
Using width detection as an example, you might do something like this:
Partial app.component.ts
import { Component, ElementRef, ViewChild, OnInit } from '@angular/core';
export class AppComponent implements OnInit {
  @ViewChild('wrapper') 
  private wrapperElement: ElementRef;
  private menuMode; // Where we'll store the resulting menu mode
  ngOnInit() {
    // Do your simple test on the container, for example
    if (this.wrapperElement.nativeElement.offsetWidth <= 720) {
        this.menuMode = "over";
    } else {
        this.menuMode = "side";
    }
  }
}
And bind the variable to the sidenav in the template.
Partial app.component.html
<div #wrapper>
    <md-sidenav-container>
        <md-sidenav #sidenav [mode]="menuMode"></md-sidenav>
        ...
</div>
The bulk of that work is just determining how you want to perform the test.
You could also just test window instead of a wrapper, but I prefer testing a wrapper.
Notes:
@HostListener("window:resize",
["$event"]), but that's outside of the scope of your original
question.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With