Search code examples
angularangular17ng-style

Angular ngStyle directive not working: style properties don't update


I'm trying to use the [ngStyle] directive in an Angular 17 app to dynamically show or hide an element, like this:

<div [ngStyle]="{visibility: loaded ? 'collapse' : 'visible' }">
    ...
</div>

where loaded is a boolean property in my component.

The problem is: this doesn't work. It correctly sets the visibility property at the start according to the initial value of loaded, but after that if I at some point change the value of loaded the visibility doesn't change accordingly. Am I missing something basic here? I've also tried with [style] instead of [ngStyle] but the result is exactly the same.

Edit: here's my imports in the component:

imports: [
    NgIf,
    ProgressBarModule,
    NgStyle,
    CommonModule
  ],

EDIT 2: after further testing, it seems that Angular is not detecting the change in the loaded property for some reason. If I inject ChangeDetectorRef into the component and manually trigger change detection, like this:

this.loaded = true;
this.cdRef.detectChanges();

it start working correctly. Note that the code that flips the loaded property is inside a Promise... can that be the issue? Are changes made inside a Promise block not auto-detected by Angular in general?


Solution

  • UPDATE:

    You have OnPush Change detection strategy enabled.

    This triggers change detection only when @Inputs of a component or browser/user events (button click)

    Read about it in details on the angular docs

    That is why the asynchronous call is not updating the UI and you have to do this.cdRef.detectChanges();


    Make sure you imported either CommonModule or NgStyle directive into the component only then will the directive work.

    CommonModule contains the directives needed for using NgStyle or NgClass.

    ...
    @Component({
         selector: '...',
         standalone: true,
         imports: [CommonModule],
        ...
    })
    export class SomeComponent {
        ...
    

    If it's standalone -> the imports should be in the imports array of the component.

    If it's modular -> go to the module, where the component is added to the declarations array and add the import.