Monitoring changes within the browser width with Angular 2 to automatically refresh the model

One of the challenges I faced in my Angular 2 application was implementing responsive design by adjusting styles based on browser window width. Below is a snippet of SCSS code showing how I achieved this:

.content{
    /*styles for narrow screens*/
    @media (max-width: 750px){
        background-color:beige;
    }
    /*styles for medium screens*/
    @media (min-width: 751px) and (max-width: 1200px) {
        background-color:red;
    }
    /*styles for wide screens*/
    @media (min-width: 1201px) {
        background-color:brown;
    }   
}

To make it easier for Angular components to respond accordingly, I created a function that determines the current width interval based on pixel values:

/* Returns which of the CSS width intervals is current*/
getWidthRange(){
    let pixelWidth = ...; //what goes here?

    if(pixelWidth < 251) return "small";
    if(pixelWidth < 451) return "medium";
    return "large"; 
}   

Each component can use this function to adjust its behavior. For example, a template might display different content based on the screen width:

<div>
    {{getWidthRange()==='small'? shortText : longText}}
</div>

In addition to this, I wanted to set up an Observable that notifies components when the browser transitions between different width ranges:

widthRangeChanges = Observable.create( observer => 
    {       
        // ? how to detect when width changes
        let oldRange = '...';
        let newRange = '...';
        if(newRange!==oldRange) observer.next(newRange);
    }
).share(); //all subscribers share same output channel

This way, components can subscribe to widthRangeChanges and update their model values accordingly. Implementing this in Angular 2 rc-6 with typescript 2.0.2 and rxjs 5 beta 11 was indeed challenging, but worth the effort.

Answer №1

To monitor window resizing events and get the client width using RxJS, you can utilize the fromEvent operator:

 const $resizeStream = Observable.fromEvent(window, 'resize')
   .map(() => {
     return document.documentElement.clientWidth;
   })
   .debounceTime(200)

   $resizeStream.subscribe(data => {
     this.width = data;
   });

Check out this Plunker Example for demonstration

Answer №2

Customized Template

<div (window:resize)="onResize($event)"></div>

export class ResizableComponent {            
      onResize(event) {
        console.log("Event details:");
        console.log("width:" + event.target.innerWidth);
        console.log("height:" + event.target.innerHeight);

        this.pixelWidth = event.target.innerWidth;
      }

      getWidthRange(){
         if(this.pixelWidth < 251) return "small";
         if(this.pixelWidth < 451) return "medium";
         return "large"; 
      }
}

Answer №3

calculateWidth() {
    return Math.max(
      document.body.scrollWidth,
      document.documentElement.scrollWidth,
      document.body.offsetWidth,
      document.documentElement.offsetWidth,
      document.documentElement.clientWidth
    );
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to implement the Active list element feature in my menu bar?

The current list element is : <li class="nav__item"><a class="nav__link nav__link--active " href="#"... The standard list element is: <li class="nav__item"><a class="nav__link " href=&quo ...

Learn how to securely download files from an Azure Storage Container using Reactjs

I'm currently working on applications using reactjs/typescript. My goal is to download files from azure storage v2, following a specific path. The path includes the container named 'enrichment' and several nested folders. My objective is to ...

Unable to utilize vue-cookies library in TypeScript environment

I have integrated vue-cookies into my app in the main.ts file: import VueCookies from 'vue-cookies'; ... const app = createApp(App) .use(IonicVue) .use(router) .use(VueCookies,{ expires: '30d', }); Despite adding the cookie v ...

Styling with CSS: How to Show an Absolutely Positioned Element in Google Chrome

I'm currently working on a CSS design that involves positioning an image within a span tag. Here's the CSS code I have: .dc-mega-icon { background-image: url(...); display: inline-block; position: absolute; top: 18px; width: ...

Creating a horizontal scrolling section for mobile devices using CSS

Looking to create a horizontal scroll area specifically for mobile devices, similar to the design seen here: https://i.sstatic.net/oSNqL.png Additionally, I want to hide the scrollbar altogether. However, when attempting to implement this, there seem to ...

The transparency of the text in my navbar is glitching when I scroll down

I'm experiencing an issue with my navbar text becoming translucent when scrolling. How can I fix this problem? Check out the picture below for more details. ...

Press the button to update several span elements

Imagine I have multiple span elements like this: <span>A</span> <span>B</span> <span>C</span> <span>D</span> and a div element (which will be converted to a button later) named "change". <div id="chan ...

Unpacking objects in Typescript

I am facing an issue with the following code. I'm not sure what is causing the error or how to fix it. The specific error message is: Type 'CookieSessionObject | null | undefined' is not assignable to type '{ token: string; refreshToken ...

Are there any alternative methods to avoid duplication of Navbar link margin classes in Tailwind CSS?

It feels really repetitive to have to add margin classes to each LI manually on a non-dynamically generated menu. It almost seems as messy as using inline style attributes... Is there a more efficient way to handle this? While it may not be a big deal fo ...

Unit Testing with Angular: Testing the setValueControl function

I am currently in the process of writing unit tests for a straightforward function that assigns controls to various values. fillFormAssociazioneVeicolo() { if (this.aaa) { setValueControl( this.aaa.targaTelaio, this.form.get(&apos ...

Mocking a third-party callback function in Jest for method implementation

Utilizing Nest + Cognito for user authentication in an application, I have a method within my Authentication service that requires testing/mocking: async cognitoRegister(userPool: CognitoUserPool, { name, password, email }: AuthRegisterInput): ...

Exploring MongoDB files easily using Angular

I am currently working on implementing a user search feature using Angular to query users from a MongoDB collection. The function on the server side is already operational and functioning correctly with Postman. However, I encountered an error on the clien ...

Using Typescript: Undefined arrays could cause issues in the array map function

Encountering a Typescript error stating that '<array name>' is possibly undefined while attempting to map over an array in Typescript. Below is an example code snippet triggering this issue: type obj = { list?: string[] }; function dem ...

What is the best way to reference a component variable property within its template without explicitly stating the variable name?

Suppose my component is managing an instance of the following class: class Person { firstName: string; lastName: string; age: number; } Is there a way to directly reference its properties in the template like this: <p>{{firstName}}</p> & ...

What causes Next.js to struggle with recognizing TypeScript code in .tsx and .ts files?

Webpages lacking a declared interface load correctly https://i.stack.imgur.com/DJZhy.png https://i.stack.imgur.com/r1XhE.png https://i.stack.imgur.com/zXLqz.png https://i.stack.imgur.com/Z1P3o.png ...

Creating TypeScript modules for npm

I have been working on creating my first npm module. In the past, when I used TypeScript, I encountered a challenge where many modules lacked definition files. This led me to the decision of developing my module in TypeScript. However, I am struggling to ...

Having trouble setting a background image for my CSS button

Recently started experimenting with button styles and I wanted to create a design where there is a background image on the left of the button with text located on the right side of the image. Here's the code snippet I've been working on. Here&apo ...

Using Angular material to display a list of items inside a <mat-cell> element for searching

Can I use *ngFor inside a <mat-cell> in Angular? I want to add a new column in my Material table and keep it hidden, using it only for filtering purposes... My current table setup looks like this: <ng-container matColumnDef="email"> < ...

Container struggling to contain overflowing grid content items

While creating a grid in nextjs and CSS, I encountered an issue. Whenever I use the following code: display: grid; The items overflow beyond the container, even though I have set a maximum width. Instead of flowing over to the next row, the items just kee ...

The XMLHttpRequest response states that the preflight request did not meet the access control check requirements

I am attempting to subscribe to a firebase cloud messaging topic by sending an http post request. var data = null; var xhr = new XMLHttpRequest(); xhr.withCredentials = true; xhr.addEventListener("readystatechange", function () { if (this.readyState ...