I have an Angular 9 app (upgraded from 7 recently, but still had same issue in 7) and in my app.component.html file I have this code below. The page loads correctly and everything looks good. But the method
getSideBarState() // returns a boolean
in both 'toggled' and 'show' ngClass get triggered and run at least 10+ times when I first start up the debugger. And then after the last one runs, it waits about ~10 secs and then ~10 get triggered again and run. And this keeps going and going endlessly being triggered and run.
Can anyone tell me why, and how to stop it from being triggered and run so many times? I only want it to run once when the app first loads.
<div class="page-wrapper" [ngClass]="{'toggled' : getSideBarState()}" (window:resize)="onResize()">
<app-sidebar></app-sidebar>
<main class="page-content">
<div class="">
<app-nav-bar></app-nav-bar>
<router-outlet (activate)="onActivate($event)"></router-outlet>
</div>
<div class="overlay" (click)="toggleSidebar()" [ngClass]="{'show' : !getSideBarState()}"></div>
</main>
</div>
This is working as per the design of Angular.
getSideBarState
will get called every time change detection runs in Angular application, on almost every life cycle hook and many more times (Which I don't know at the moment), because you are using function (which returns something to the template) in the template instead of simple variable Binding.
How you avoid this?
In order to avoid call you function getSideBarState
in ngOnInit
or other suitable life cycle hook and assign the return value to one variable and then bind to that variable in the template, in that way it won't run multiple times.
For example -
ngOnInit() {
getSideBarState();
}
getSideBarState() {
... Some calculations (here `classState` is variable)
classState = true/false; // return value
}
<div class="page-wrapper" [ngClass]="{'toggled' : classState}" (window:resize)="onResize()">
<app-sidebar></app-sidebar>
<main class="page-content">
<div class="">
<app-nav-bar></app-nav-bar>
<router-outlet (activate)="onActivate($event)"></router-outlet>
</div>
<div class="overlay" (click)="toggleSidebar()" [ngClass]="{'show' :!classState}"></div>
</main>
</div>
Hope this answer will help you.