Angular Classes not showing up on mobile and tablet

Discussão em 'Angular' iniciado por Yousef Marey, Dezembro 19, 2024.

  1. Yousef Marey

    Yousef Marey Guest

    I have 3 complete different designs for mobile, tablet, and desktop. I decided that I will use Angular Signals with media queries to know the state of the angular application. The bug is that despite Angular correctly recognizing that we are in a particular mode (tablet mode for example), some classes are not rendered in the NgClass directive. isTablet() is working in both the component TS and template HTML, but the NgClass does not render the appropriate classes when isTablet() is true. All the media query work is done from this Media Query Angular Tutorial. The service is provided below for convenience.

    Media Query Service:

    export class MediaQueryService {
    // important breakpoints that we care about
    private readonly BREAKPOINTS = {
    lg: '1200px',
    md: '768px',
    sm: '0px',
    }

    private activeMediaQueries: {[key: string]: Observable<boolean>} = {}



    mediaQuery(type: 'min' | 'max', breakPoint: keyof typeof this.BREAKPOINTS): Observable<boolean> {


    const mediaId = `${type}-${breakPoint}`;

    if(mediaId in this.activeMediaQueries) {
    return this.activeMediaQueries[mediaId]
    }


    const mqText = `(${type}-width: ${this.BREAKPOINTS[breakPoint]})`;
    const mediaQuery = window.matchMedia(mqText); // this returns something called the MediaQueryList.



    const dynamicMediaQuery = fromEvent<MediaQueryList>(mediaQuery, 'change').pipe(
    startWith(mediaQuery), // sync emit all values passed to the operator
    map((query: MediaQueryList)=> query.matches)
    )

    this.activeMediaQueries[mediaId] = dynamicMediaQuery;
    return dynamicMediaQuery;
    }



    }



    How I implement in my component is as follows:

    export class BillsComponent {
    #mediaQueryService = inject(MediaQueryService)
    isMobile = toSignal(this.#mediaQueryService.mediaQuery('max', 'md'));
    isDesktop = toSignal(this.#mediaQueryService.mediaQuery('min', 'lg'));
    isTablet = computed(() => (!this.isMobile() && !this.isDesktop()))

    }


    However, the particular classes in the NgClass directive do not work.

    <!--
    'container br bg-white' are not implemented even when on mobile or tablet (they exist.)
    -->
    <div [ngClass]="{'container br bg-white p-300 mt-300': isMobile() || isTablet(), 'container br bg-white p-400': isDesktop()}">
    <app-header [title]="'Recurring Bills'">See Details</app-header>
    <div class="flex mt-400">
    <app-bill [amount]="'$190.00'" [title]="'Paid Bills'" [color]="'#277C78'"></app-bill>
    <app-bill [amount]="'$194.98'" [title]="'Total Upcoming'" [color]="'#F2CDAC'"></app-bill>
    <app-bill [amount]="'$59.98'" [title]="'Due Soon'" [color]="'#82C9D7'"></app-bill>
    </div>
    </div>
    <div class="text-preset-1">
    <!-- This is correctly rendered when we adjust the view -->
    <p>isMobile or Tablet is {{isMobile() || isTablet()}}</p>
    <p>isDesktop is {{isDesktop()}}</p>
    </div>


    My guess would be something regarding the change detection?

    Any help would be appreciated.

    Continue reading...

Compartilhe esta Página