0

I used @angular/material:navigation <component-name> to install Schematics, for having a responsive design.

My ts looks like:

import { Component, ElementRef, ViewChild } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Observable } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss'],
})
export class NavbarComponent {

  isSmall$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Small)
    .pipe(
      map(result => result.matches),
      shareReplay()
    );
    
  constructor(private breakpointObserver: BreakpointObserver) {}

}

I changed isHandset to isSmall. My menu Icon disappears at 600px, but I don't want it to be disappeared. I can't change my button that it should stay between 0px and 960px. Is that possible?

Here is a table, how the breakpoints are defined.

Is it possible for me to use 2 breakpoints on one button, for example:

 <button 
        type="button"
        aria-label="Toggle sidenav"
        mat-icon-button
        (click)="drawer.toggle()"
        *ngIf="(isSmall$ | async)"> 
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>

That's how my button looks like, but I want it to be:

 <button 
        type="button"
        aria-label="Toggle sidenav"
        mat-icon-button
        (click)="drawer.toggle()"
        *ngIf="(isSmall$ && isXSmall | async)"> 
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>

I added to ngIf *ngIf="(isSmall$ && isXSmall | async)"> , I know that this isn't possible, but that is how I want it to be. Two breakpoints, that my menu icon stays active until I am at 960px, after that it should disappear. None of the Angular breakpoint options stays between 0 and 960px.

If you guys could help me I would really appreciate it.

2 Answers 2

1

Well, my suggestion is to use CSS breakpoints to handle layout responsiveness. Consuming Observables to handle layout goes against the rules of separating “layout” and “logic”.

So try using mediaqueries to select the button and using display:none when you want to hide it.

Place in the css file of the component something like:
`

@media (min-width: 960px) {
        Button {
            Display:none !important;
         }
    }

On the other hand, if you really want to use the observables, please try: ....*ngIf=“(isSmall$ | async) || (isXSmall$ |async)”

First, doublecheck how you named “isXSmall” because seems you wrote it without $ when you are naming them ending with $. Then, remember that each Observable needs to be piped with “async”. And finally, your logic must be || because when “isSmall” it can not be “isXSmall”. You need one of them to be evaluated to true, so || is your friend.

EDIT: Seems you are not implementing the isXSmall$ observable. Please add the following:

isXSmall$: Observable = this.breakpointObserver.observe(Breakpoints.XSmall) .pipe( map(result => result.matches), shareReplay() );

The valid Breakpoints for cdk/layout are:

const Breakpoints: { XSmall: string; Small: string; Medium: string; Large: string; XLarge: string; Handset: string; Tablet: string; Web: string; HandsetPortrait: string; TabletPortrait: string; WebPortrait: string; HandsetLandscape: string; TabletLandscape: string; WebLandscape: string; };

EDIT3

Btw, you can check for two conditions in the “observe”. So modify your button so the *ngIf is

*ngIf="(isSmallOrXSmall$ | async)"

And modify your code to be:

isSmallOrXSmall$: Observable<boolean> = this.breakpointObserver.observe( [Breakpoints.XSmall, Breakpoints.Small]) .pipe( map(result => result.matches), shareReplay() );

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

3 Comments

Thank you soo much for your comment and your time for helping me out. I used your second advice with *ngIf=“(isSmall$ | async) || (isXSmall$ |async)”, but I get the error Property 'isXSmall$' does not exist on type 'NavbarComponent. What has to be done in my ts file to avoid that error? I just copied isSmall$: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.Small) .pipe( map(result => result.matches), shareReplay() ); and changed the name of isSmall to isXSmall, but is it how I have to do? It kinda feels wrong and doesn't work.
Edited. Seems you are not implementing the isXSmall observable?
It worked! I didn't know, that this is possible with checking for two conditions. I hope that your answer will also reach other questioners in the future. Thanks a lot!
0

Could you accomplish the wanted behaviour by using 2 classes instead of an if?

<button 
   type="button"
   aria-label="Toggle sidenav"
   mat-icon-button
   [class.is-small]="isSmall$ | async"
   [class.is-xsmall]="isXSmall | async"
   (click)="drawer.toggle()"> 
   <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
</button>

css file:

.is-small,
.is-xsmall {
   display: none

}

If not you can change the isSmall & isXSmall observables to one observable that returns a number, so you can do this: *ngIf="(size$ | async) < 2"

3 Comments

First of all, thank you so so much for your effort by helping me out. I tried your method, but I can't get rid of the error Property 'isXSmall' does not exist on type 'NavbarComponent. I don't really know how to implement it in my ts file, i tried by changing the name of isSmall to isXSmall and so I had two breakpointObserver, but is it how it has to be done?
I see you already have an answer which is way better then mine (I thought you needed the two observables but media-queries are the way to go). And yeah you would need two observables for my solution to work
I thank you very much too for your help and that you took the time for me, I was so desperate. Finally it works! But without both of your helps, I would not have made it work.

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.