Search code examples
angulartypescriptangular-materialmedia-queries

What is the benefit of using the Angular Material BreakpointObserver API over a simple Media Query?


I've been experimenting with Angular Material and found myself questioning the benefit of using the built in BreakpointObserver API over a simple media query?

Or rather than being more beneficial it really comes down to what you want to achieve?


Solution

  • It's usually used to make the page different for mobile and desktop. For example you can pipe the breakpoints in your JavaScript files and make it react to the changes.

    For example you can navigate to a full-page if you try to search in a input field on mobile device, and just let the user search on desktop

      navigateToSearchPageIfMobile = () => {
        combineLatest([this.isMobile$, this.searchActive$]).pipe(
          takeUntil(this.unsubscribe$),
          filter(([isMobile, active]) => isMobile && active))
          .subscribe(() => {
            this._router.navigate(["./", this._languageService.lang$.value, paths.SEARCH], {queryParams: {search: this.searchText$.value}})
          })
      }
    

    Or simply just data driven design with *ngif

    Or you can make your own breakpoint service:

    export class BreakpointService {
    
        constructor() {
            this.onLoad()
            this.onResize()
        }
    
        private readonly breakpoints = {
            xs: 0,
            sm: 576,
            md: 768,
            lg: 992,
            xl: 1200
        }
    
        private currentWidthSub$ = new BehaviorSubject<number>(null)
        public currentWidth$ = this.currentWidthSub$.asObservable()
    
        isMobile$ = this.currentWidth$.pipe(map(x => x < this.breakpoints.md), distinctUntilChanged())
    
        currentBreakpoint$ = this.currentWidthSub$.pipe(
            filter(width => width != null),
            map(width => {
                return Object.keys(this.breakpoints).map((key) => {
                    return {
                        key: key,
                        value: this.breakpoints[key] - 1
                    }
                }).reverse().find(x => x.value < width).key
            }),
            distinctUntilChanged()
        )
    
        private onResize = () => {
            fromEvent(window, 'resize').subscribe(resize => {
                this.currentWidthSub$.next(resize.currentTarget["innerWidth"])
            })
        }
    
        private onLoad = () => {
            fromEvent(window, 'load').subscribe(load => {
                this.currentWidthSub$.next(load.currentTarget["innerWidth"])
            })
    
        }  
    }