Angular window resize event
Solution 1
<div (window:resize)="onResize($event)"
onResize(event) {
event.target.innerWidth;
}
or using the HostListener decorator:
@HostListener('window:resize', ['$event'])
onResize(event) {
event.target.innerWidth;
}
Supported global targets are window
, document
, and body
.
Until https://github.com/angular/angular/issues/13248 is implemented in Angular it is better for performance to subscribe to DOM events imperatively and use RXJS to reduce the amount of events as shown in some of the other answers.
Solution 2
I know this was asked a long time ago, but there is a better way to do this now! I'm not sure if anyone will see this answer though. Obviously your imports:
import { fromEvent, Observable, Subscription } from "rxjs";
Then in your component:
resizeObservable$: Observable<Event>
resizeSubscription$: Subscription
ngOnInit() {
this.resizeObservable$ = fromEvent(window, 'resize')
this.resizeSubscription$ = this.resizeObservable$.subscribe( evt => {
console.log('event: ', evt)
})
}
Then be sure to unsubscribe on destroy!
ngOnDestroy() {
this.resizeSubscription$.unsubscribe()
}
Solution 3
@Günter's answer is correct. I just wanted to propose yet another method.
You could also add the host-binding inside the @Component()
-decorator. You can put the event and desired function call in the host-metadata-property like so:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
host: {
'(window:resize)': 'onResize($event)'
}
})
export class AppComponent{
onResize(event){
event.target.innerWidth; // window width
}
}
Solution 4
The correct way to do this is to utilize the EventManager class to bind the event. This allows your code to work in alternative platforms, for example server side rendering with Angular Universal.
import { EventManager } from '@angular/platform-browser';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Injectable } from '@angular/core';
@Injectable()
export class ResizeService {
get onResize$(): Observable<Window> {
return this.resizeSubject.asObservable();
}
private resizeSubject: Subject<Window>;
constructor(private eventManager: EventManager) {
this.resizeSubject = new Subject();
this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this));
}
private onResize(event: UIEvent) {
this.resizeSubject.next(<Window>event.target);
}
}
Usage in a component is as simple as adding this service as a provider to your app.module and then importing it in the constructor of a component.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-component',
template: ``,
styles: [``]
})
export class MyComponent implements OnInit {
private resizeSubscription: Subscription;
constructor(private resizeService: ResizeService) { }
ngOnInit() {
this.resizeSubscription = this.resizeService.onResize$
.subscribe(size => console.log(size));
}
ngOnDestroy() {
if (this.resizeSubscription) {
this.resizeSubscription.unsubscribe();
}
}
}
Solution 5
Here is a better way to do it. Based on Birowsky's answer.
Step 1: Create an angular service
with RxJS Observables.
import { Injectable } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';
@Injectable()
export class WindowService {
height$: Observable<number>;
//create more Observables as and when needed for various properties
hello: string = "Hello";
constructor() {
let windowSize$ = new BehaviorSubject(getWindowSize());
this.height$ = (windowSize$.pluck('height') as Observable<number>).distinctUntilChanged();
Observable.fromEvent(window, 'resize')
.map(getWindowSize)
.subscribe(windowSize$);
}
}
function getWindowSize() {
return {
height: window.innerHeight
//you can sense other parameters here
};
};
Step 2: Inject the above service
and subscribe to any of the Observables
created within the service wherever you would like to receive the window resize event.
import { Component } from '@angular/core';
//import service
import { WindowService } from '../Services/window.service';
@Component({
selector: 'pm-app',
templateUrl: './componentTemplates/app.component.html',
providers: [WindowService]
})
export class AppComponent {
constructor(private windowService: WindowService) {
//subscribe to the window resize event
windowService.height$.subscribe((value:any) => {
//Do whatever you want with the value.
//You can also subscribe to other observables of the service
});
}
}
A sound understanding of Reactive Programming will always help in overcoming difficult problems. Hope this helps someone.
Related videos on Youtube

DanAbdn
Programmer based at Aberdeen, UK. Primarily interests relate around web technologies: MVC 6 with C# Single Page Applications (SPA) - Angular2 SignalR WebGL / OpenGL Visual Studio 2015
Updated on July 29, 2022Comments
-
DanAbdn 10 months
I would like to perform some tasks based on the window re-size event (on load and dynamically).
Currently I have my DOM as follows:
<div id="Harbour"> <div id="Port" (window:resize)="onResize($event)" > <router-outlet></router-outlet> </div> </div>
The event correctly fires
export class AppComponent { onResize(event) { console.log(event); } }
How do I retrieve the Width and Height from this event object?
Thanks.
-
Sasxa over 7 yearsNot really an Angular question. look at the window object. You can get it's
innerHeight
andinnerWidth
properties.. -
Pankaj Parkar over 7 years@Sasxa is correct, you just need to do
console.log(event.target.innerWidth )
-
DanAbdn over 7 yearsThanks for the info Sasxa/Pankaj - I wasn't sure whether it was just a plain javascript thing or a Typescript thing or an Angular event thing. I'm climbing a very steep learning curve for myself here and appreciate your input.
-
-
Clement about 7 yearsIs there any documentation about the syntax you use: window:resize ?
-
Günter Zöchbauer about 7 years@Clement haven't found docs. But it was repeatedly mentioned and is officially supported. Docs are not perfect yet.
-
Clement about 7 yearsOkay, so this is a kind of syntaxic sugar build into angular2 ?
-
Günter Zöchbauer about 7 years
-
Tomato over 6 yearsI've tried every method on this page and it seems none of them work. Is there any official documentation about this.
-
Günter Zöchbauer over 6 yearsSeems you're doing something wrong ;-) I'd suggest you create a new question with the code that allows to reproduce the problem.
-
Giridhar Karnik over 6 yearshow is the viewport height obtained on load?
-
Zuriel over 6 yearsI believe this is a error: this.height$ = (windowSize$.pluck('height') as Observable<number>).distinctUntilChanged();Observable<number>).distinctUntilChanged(); looks like you pasted in the distinctUntilChanged() twice in a row
-
John about 6 years@GiridharKarnik, have you tried doing a
window.innerWidth
insidengOnInit
, orngAfterViewInit
methods? -
John about 6 years@Tomato The API-reference can be found here Many of the references are autogenerated (I presume), and have a lack of examples or detailed explanation. Some api-references have a lot of examples. I could not find a concrete example from the docs about this though. Maybe it is hidden somewhere :P
-
Giridhar Karnik about 6 years@John, if I do that, won't it be an on shot thing? Will ngOnInit or ngAfterViewInit fire each time I resize?
-
John about 6 years@GiridharKarnik Yes, you are correct. They will only fire once (each time the component is created). If you want to check every time you resize, use the
@HostListener
. -
gnganapath about 6 yearsinside the onResize(event) let screenHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); It's working
-
Giridhar Karnik about 6 yearsI did not get you, eloborate please.
-
Gaurav Sharma almost 6 yearsperfect answer.. i do believe @HostListener is the cleaner way :) but make sure to import the HostListener first using
import { Component, OnInit, HostListener } from '@angular/core';
-
Anand Rockzz almost 6 yearshere is a reference of how its used
-
Mark Pieszak - Trilon.io almost 6 yearsChange detection won't be fired as you're doing this event outside of Angular, believe that's what he meant.
-
Matt Sugden almost 6 yearsI had an error saying 'pluck' does not exist on type BehaviorSubject. Changing the code to this.height$ = windowSize$.map(x => x.height) worked for me.
-
user3170530 almost 6 yearsThis doesn't ever fire on mobile as far as I can tell. How do you get the initial window size with this approach?
-
cgatian almost 6 yearsMobile does not have a
window
object, just as a server doesn't have awindow
. Im not familiar with the different mobile configurations but you should be able to easily adapt the above code to bind to the correct global event listener -
ghiscoding over 5 years@GiridharKamik Can you provide a solution that would subscribe on width & height at same time, which we could subscribe to both the width, height in 1 simple subscribe
-
Armeen Moon over 5 years@cgatian I'm a noob but this seems like the right answer. Unfortunatly I'm having no luck making my subscription Log in the component. Could you add to the answer how to subscribe to this in a component so that one can see the updates?
-
Armeen Moon over 5 years@cgatian I'll make a plunker but this seemed to not work . The filter in the service seems weird tho stackoverflow.com/q/46397531/1191635
-
Zymotik over 5 yearsQuick tip: If want to trigger on first load too, implement ngAfterViewInit from @angular/core. angular.io/api/core/AfterViewInit
-
Drenai over 5 yearsWould this work with Server Side Rendering or with WebWorkers...
height: window.innerHeight
? -
Drenai over 5 years@cgatian
Mobile does not have a window object
.... why do you think mobile browsers don't have a window object? -
cgatian over 5 yearsI took the comment as he was using Ionic or NativeScript.
-
tom almost 5 yearsUsing Angular 6,
@HostListener('window:resize', ['$event'])
works for me, but only withwindow
. Replacingwindow
bydocument
orbody
, the event is not triggered at all. -
Günter Zöchbauer almost 5 yearsAngular only providers what the browser supports. If
document
of body don't emit that event, youcan't getit from Angular. Consult the browser docs which events are amitted by which object. -
jcdsr over 4 yearsI found this as the best solution, however, this only works when the window is resized, but not when loads or when the router change. Do you know, how to apply with router change, reload or load?
-
jcdsr over 4 yearsThis is NOT THE BEST SOLUTION, hostlistener fires on every pixel, and multiple times, plus, if this is implemented in multiple components, will cause a lack or delays to show or change the elements
-
jcdsr over 4 yearsin fact, this will slow the app!
-
Günter Zöchbauer over 4 yearsYou're still right :D I added a link to an issue where plans for improvement are discussed.
-
Jette over 4 yearsThe only way that has worked for me. Thanks!! :-) ... I just had to adjust your import. Perhaps my rxjs is newer:
import { fromEvent, Observable,Subscription } from "rxjs";
-
jcdsr over 4 yearswhat about using debounceTime?
-
Günter Zöchbauer over 4 yearsIs a good idea but works better with the other answers with imperative event subscription.
-
jcdsr over 4 yearsSure, however, for those who want to know how works HostListener with debounceTime, follow the link below plnkr.co/edit/3J0dcDaLTJBxkzo8Akyg?p=preview
-
Günter Zöchbauer over 4 years@jcdsr Nice one!
-
Deepak Thomas over 4 yearsWhere can I add debounce(1000) in this?
-
Chris Stanley over 4 yearsSorry for late reply: to add debounce, you'll want to use
this.resizeSubscription$ = this.resizeObservable$.pipe(debounceTime(1000)).subscribe( evt => { console.log('event: ', evt) })
-
Thanveer Shah over 4 yearsI want to change a varibale from counter = 6 to count = 0 at max-width 767px, How do i do that ?
-
Darren Street over 3 yearsif you want to detect window resizes then Angular Material Breakpoint Observer handles already material.angular.io/cdk/layout/overview
-
Martin Volek over 3 yearsBut this does not detect only windows resize, but any element resize.
-
DanielWaw over 3 yearsYou can add a function to the service and trigger it in component @jcdsr: getScreenSize() { this.onResize$.emit({ width: window.innerWidth, height: window.innerHeight }); }
-
Deniss M. about 3 yearsthis should be the accepted answer. Has everything needed + this is angular CDK inbuilt functionality.
-
dude about 3 yearsI'm using
@HostListener('window:resize') @throttle(300)
, but do I need to unsubscribe to the window:resize event and if so, how? -
Günter Zöchbauer about 3 years@dude no. As a rule of thumb, if you subscribe imperatively (calling
foo.subscribe(evt => ...)
, you should explicitly unsubscribe, if you declarativly subscribe, Angular will take care automatically. -
dude about 3 years@GünterZöchbauer Thanks for your reply. Do you have any reference for this?
-
Totati about 3 years@MarkPieszak-Trilon.io It will fire, cause it runs inside the zone. I don't see calling the subscribe inside
runOutsideAngular
-
jcdsr about 3 yearsdoesn't work for server-side or in angular universal
-
Totati almost 3 yearsHi, consider my answer, stackoverflow.com/a/57131782/4797961 debounceTime won't reduce change detection cycles.
-
cgatian almost 3 yearsSorry I acknowledge that comment may be incorrect and misleading. I don't know about mobile
-
Sean Halls over 2 yearsThis is nice to know... but just a note... this is material library angular docs, not official documentation from Angular itself. Sort of suggestive that all the breakpoints will follow Material guidelines OOTB.
-
oomer over 2 yearsThe only thing i couldn't figure out right away was that the
onResize
method has to be defined right after the @HostListener declaration in a kind of a callback way. Had not used this API before. -
Günter Zöchbauer over 2 years@oomer
@HostListene()
is an annotation toonResize
similar to@Input
,@Output()
,@ViewChild()
@Inject()
, ... and annotations always apply to the following element. -
CRice over 2 yearsfor debounce, import { debounceTime } from 'rxjs/operators';
-
Jandro Rojas almost 2 yearsthis answer needs to be upvoted more. In terms of performance and compatibility, this is the best solution
-
pistol-pete almost 2 yearsTried this and got it working....the performance was drastically slower than options above.
-
Totati over 1 year@pistol-pete I've added an example to show how high performant this is.
-
GusSL over 1 yearNote:
addGlobalEventListener
is @deprecated as of Angular 12 — No longer being used in Ivy code. To be removed in version 14. -
GusSL over 1 yearin the service constructor, you have to use
.pipe()
to usedistinctUntilChanged()
,pluck()
andmap()
, both imported fromrxjs/operators
used like this:.pipe(map())
. Also, just usefromEvent()
imported directly fromrxjs
instead ofObservable.fromEvent()
-
Totati over 1 yearThe global targets has been moved, currently you can find them here: github.com/angular/angular/blob/master/packages/compiler/src/…
-
Totati over 1 yearIn spite of using
debounceTime
and running your subscribe callback less, Angular will run change detection on every event, as it's triggered inside the zone. You should check my answer that eliminates this problem. -
daniol over 1 yearThis requires Angular Material components
-
Totati over 1 yearNo, it requires npmjs.com/package/@angular/cdk, I start my answer with that.
-
Felipe Morais about 1 year@daniol add cdk to your project: ng add @angular/cdk