netik
netik

Reputation: 1826

How to avoid ExpressionChangedAfterItHasBeenCheckedError when changing parent value from within a child?

In our application, the router-outlet is place within a togglable sidebar inside the app.component. The visibility of the sidebar is managed by the SideBarService. The button used for toggling the sidebar uses an *ngIf to show either a show or hide arrow.

<div id="sidebar" [style.width.px]="this.sideBarService.getWidth()">
    <router-outlet></router-outlet>
    <a id="sidebar-toggle-button" (click)="toggleSideBar()">
        <div *ngIf="this.sideBarService.hidden; then inactive else active"></div>
        <ng-template #active><i class="material-icons ui-icon-chevron-left"></i></ng-template>
        <ng-template #inactive><i class="material-icons ui-icon-chevron-right"></i></ng-template>
    </a>
</div>

And the service:

@Injectable()
export class SideBarService{
    public width: number;
    public hidden;

    public changeWidth(width: number): void {
        this.width = width;
    }

    public getWidth(): number {
        return (this.hidden === true ? 0 : this.width);
    }

    public hide(): void {
        this.hidden = true;
    }

    public show(): void {    
        this.hidden = false;
    }
}

Now, the place where the sideBarService.hidden value is being changed is from components shown in the router-outlet. Maybe that is the reason why I'm constantly getting the following error:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: undefined'. Current value: 'ngIf: false'.

I believe it is because the change is triggered from a child component of the app-component. But I do not understand how I should solve this issue.

Upvotes: 0

Views: 1939

Answers (1)

Lia
Lia

Reputation: 11982

you can use angular ChangeDetectorRef that Checks view and its children. Use in combination with detach to implement local change detection checks.

import { Component , ChangeDetectorRef } from '@angular/core';

...

constructor(private cdr:ChangeDetectorRef){}

and after hide call:

this.cdr.detectChanges();

Upvotes: 3

Related Questions