Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExpressionChangedAfterItHasBeenCheckedError when dispatching action from ngOnInit

I'm subscribing to ngrx store in the constructor of my AppComponent:

export class AppComponent {
    submenuItems: Observable<Array<INavigationBarItem>>;

    constructor(private store: Store<AppState>) {
        this.submenuItems = this.store.select<Array<INavigationBarItem>>((state: AppState) => state.submenu.items);
    }
}

Then, I'm dispatching an action in my other component's ngOnInit method, like this:

export class SearchPageComponent implements OnInit {
    constructor(private store: Store<AppState>) { }

    ngOnInit(): void {
        this.store.dispatch(new SubmenuAction([
            { title: 'Search', isActive: true },
            { title: 'New Group' }
        ]));
    }
}

And the result of this interaction is the ExpressionChangedAfterItHasBeenCheckedError exception. If I move that dispatch call to the constructor of my child component, then no error is thrown, but I'm wondering if that's only by chance. Also I don't think putting this inside constructor body is a good idea.

Each of my components will need to have this store.dispatch call - as you can see, its purpose is to produce a submenu data which will be different from page to page. How to get around this exception?

like image 334
Marek M. Avatar asked Jul 24 '17 13:07

Marek M.


2 Answers

Moving the dispatch calls onto constructor from ngOnInit worked for me.

export class SearchPageComponent implements OnInit {
constructor(private store: Store<AppState>) { 
 this.store.dispatch(new SubmenuAction([
        { title: 'Search', isActive: true },
        { title: 'New Group' }
    ]));
}

    ngOnInit(): void { }
}
like image 137
stak Avatar answered Oct 29 '22 19:10

stak


I encountered this problem a couple of times, and figured it would be a problem with Angular zone management. What I did is more like a hack, but maybe it solves your problem too:

ngOnInit(): void {
    setTimeout(() => this.store.dispatch(new SubmenuAction([
        { title: 'Search', isActive: true },
        { title: 'New Group' }
    ])), 0);
}
like image 38
Giacomo Voß Avatar answered Oct 29 '22 18:10

Giacomo Voß