Vladislav Nikolayev
Aug 9, 2017 · 1 min read

Nice post! But I’m still running in a problem with ContentChildren.
Let’s say, I have tabs and tab components:

@Component({
selector: 'tabs',
template: `<ng-content></ng-content>`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TabsComponent implements AfterContentInit {
@ContentChildren(TabComponent) tabs: QueryList<TabComponent>;

ngAfterContentInit(): void {
if (0 < this.tabs.length) {
this.activate(this.tabs.first);
}
}

activate(activatedTab: TabComponent) {
this.tabs.forEach(tab => tab.active = false);
activatedTab.active = true;
}
}
@Component({
selector: 'tab',
template: `<ng-content></ng-content>`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TabComponent {
@Input() title: string;
@Input() @HostBinding('class.is-active') active: boolean = false;
}

So ContentChildren are available only in ngAfterContentInit, and that’s exactly where I’m setting first tab active.

The problem is, I get ExpressionChangedAfterItHasBeenCheckedError only because of *ngFor:

<tabs>
<tab *ngFor="let item of items" [title]="item.name">
<another-component [item]="item"></another-component>
</tab>
</tabs>

If I make activate() timed out the error goes away.

Could you please advise some solution to this?

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade