O.MeeKoh
O.MeeKoh

Reputation: 2136

Changing value in component's property does not trigger change detection? But works when clicking the component?

I have a very simple requirement. When the property value of hideToolBarHeader is set to true hide the toolbar header using [ngClass] ="{'my-class': hideToolBarHeader}. The value incoming value is coming from a service. This service looks like this:

`@Injectable({
  providedIn: 'root'
})
export class HeaderService {
  hideToolbarHeader$: ReplaySubject<boolean> = new ReplaySubject(1);  

  constructor() { }

  hideToolbar(hideToolbar: boolean): void{
    this.hideToolbarHeader$.next(hideToolbar); 
    console.log('[Inside HeaderService]');   
    this.hideToolbarHeader$    
  }

}`

The component looks like this:

`ngOnInit(){           
    this.headerService.hideToolbarHeader$.subscribe((value) => {
      console.log('EXECUTED WITH VALUE', value)
      this.hideToolBarHeader = value;     
    })  
}`

The console logs the correct value.

Components html template:

`<div class="toolbar" [class.mat-elevation-z7]="isSticky" [ngClass]="{'hide-toolbar': hideToolBarHeader }" >   

    <mat-toolbar #toolbarDiv color="primary" [ngStyle]="{backgroundColor: (isSticky) ? null : 'transparent'}">
...
</mat-toolbar>`

The change detection does not get triggered in the toolbar component. It is worth noting that the header component is already instantiated and created while the component that is triggering the value change comes later.

I have tried: - forcing change detection to run manually using ChangeDetectorRef no luck. - changing the hideToolbarHeader$ from Subject, to BehaviorSubject to ReplaySubject

I have the value of this.hideToolBarHeader displaying in the template p tag. I can see the value is correct in the console. The value only changes when I click the nav header. Sometimes it will randomly change after I scroll up and down a bit. What is happening?

Upvotes: 0

Views: 651

Answers (1)

Adrian Brand
Adrian Brand

Reputation: 21628

Use the async pipe on the observable instead of subscribing

hideToolbarHeader$ = this.headerService.hideToolbarHeader$;

and in the template

[ngClass]="{'hide-toolbar': (hideToolbarHeader$ | async) }"

Upvotes: 0

Related Questions