Home > Enterprise >  Why is ngClass not updating when store is updated by route change?
Why is ngClass not updating when store is updated by route change?

Time:05-04

Here is a stackblitz: https://stackblitz.com/edit/angular-esn4jk?file=src/app/app.module.ts

I want to be able to toggle between modes basically for the example I use red and green, I have two buttons:

<button [ngClass]="{ active: !(isGreen$ | async) }" (click)="redColor()">
  {{ 'red' | translate }}
</button>

<button [ngClass]="{ active: (isGreen$ | async) }" (click)="greenColor()">
  {{ 'green' | translate }}
</button>

<br />

{{ color$ | async | translate }}

<br />

<router-outlet></router-outlet>

the typescript is like this:

  isGreen$ = this.store.select(getColor).pipe(map((c) => c === 'green'));
  color$ = this.store.select(getColor);

  constructor(private store: Store<RootState>, private router: Router) {}

  ngOnInit(): void {}

  redColor(): void {
    this.router.navigate(['']);
  }

  greenColor(): void {
    this.router.navigate(['green']);
  }

Then I have a green component and a red component. Default route goes to red, green route goes to green. Each component fires an event in it's ngoninit to activate its color.

The color displays correctly between the curly braces but the ngclass does not want to work the way I want it. When directly navigating to green via the address bar in the browser the wrong button is active, updating the language fixes it.

CodePudding user response:

Because console is showing Expression has changed error. you can read more about it here :- https://angular.io/errors/NG0100

Either you can manually trigger change detection using detectChanges method inside your isGreen map like shown below :-

isGreen$ = this.store.select(getColor).pipe(
    map((c) => {
      const val = c === 'green';
      setTimeout(() => this.cd.detectChanges());
      return val;
    })
  );

Cd is reference of Change detector ref. or add a delay to your subscription like below :-

isGreen$ = this.store.select(getColor).pipe(
    delay(1),
    map((c) => c === 'green')
  );

I would prefer the delay one.

  • Related