2

I am new to Angular and can't find anything which explains what the precise meaning of these lines of the code generated from the ng generate @angular/material:material-nav.

The following lines in particular are unclear to me:

[attr.role]="isHandset ? 'dialog' : 'navigation'"
[mode]="(isHandset | async)!.matches ? 'over' : 'side'"
[opened]="!(isHandset | async)!.matches">

More specifically, what are these properties (where can I see them?), I am also unclear as to what many of the words mean for example matches or the | character? Any explanation or reference to documentation would be helpful.

The full HTML of the generated command is here:

<mat-sidenav-container class="sidenav-container">
  <mat-sidenav
    #drawer
    class="sidenav"
    fixedInViewport="true"
    [attr.role]="isHandset ? 'dialog' : 'navigation'"
    [mode]="(isHandset | async)!.matches ? 'over' : 'side'"
    [opened]="!(isHandset | async)!.matches">
    <mat-toolbar color="primary">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)!.matches">
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>
      <span>Application Title</span>
    </mat-toolbar>
  </mat-sidenav-content>
</mat-sidenav-container>

And the corresponding .ts file:

import { Component } from '@angular/core';
import { BreakpointObserver, Breakpoints, BreakpointState } from '@angular/cdk/layout';
import { Observable } from 'rxjs';

@Component({
  selector: 'newnav',
  templateUrl: './newnav.component.html',
  styleUrls: ['./newnav.component.css']
})
export class NewnavComponent {
  isHandset: Observable<BreakpointState> = this.breakpointObserver.observe(Breakpoints.Handset);
  constructor(private breakpointObserver: BreakpointObserver) {}
}
1
  • if @Phil answer satisfies you, you should mark his answer as correct. Thank you. Commented May 13, 2018 at 18:06

1 Answer 1

3

Breakpoint(Observer) according to this tutorial: https://alligator.io/angular/breakpoints-angular-cdk/

The Angular CDK has a layout package with services that make it easy to detect viewport sizes and matches against media queries. This allows you full control over the UI and to adapt to different screen sizes.

So a breakpoint is the turning point when, for example, a resolution is not considered landscape-mode anymore, but portrait-mode. Or in the case of isHandset, when the resolution is small enough to be "officially" considered a handset/mobile-device.

The Observable in isHandset: Observable<BreakpointState> means the Angular CDK framework injects an RXJS stream rather than a static value. So you need to subscribe to the stream in order to get the last value and all subsequent updates.

isHandset | async means Angular's async-Pipe is being used. Async-pipe automatically subscribes to a stream, returns the value, triggers change detection and unsubscribes from a stream (it is important to unsubscribe to avoid memory leakage).

The !. in (isHandset | async)! is a not-null assertion, preventing from an error being thrown when accessing a property if isHandset has no value in the stream yet. https://angular.io/guide/template-syntax#expression-operators

The ! in !(isHandset | async)!.matches flips the boolean-result of the matches-check

The evaluation ? ifTrue : ifFalse is the if-else-operator known to many programming languages. And [something] is Angular's way of putting data from the parent component to the child. So as result, the line [mode]="(isHandset | async)!.matches ? 'over' : 'side'" passes over a string-value as the @Input-configuration of the module, based on whether you are on the mobile or not.

These should be all the hard parts in the code. If you have further questions, feel free to ask.

Sign up to request clarification or add additional context in comments.

9 Comments

Mind shedding some light on [attr.role]="isHandset ? 'dialog' : 'navigation'" :)
Seems like that line might be generated incorrectly and thus be a bug.
@IngoBürk I ain't sure but could it be this
Sorry, I meant it looks like a bug because isHandset is an observable and for the role attribute it's not being subscribed.
BTW, I am kind of disappointed the Google team itself doesn't follow it's code guidelines and use $ at the end of Observable-variables
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.