diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index 705cded3df..deb7709f29 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -301,12 +301,15 @@ function refreshDescendantViews() { executeInitHooks(viewData, tView, creationMode); } refreshDynamicEmbeddedViews(viewData); + + // Content query results must be refreshed before content hooks are called. + refreshContentQueries(tView); + if (!checkNoChangesMode) { executeHooks(directives !, tView.contentHooks, tView.contentCheckHooks, creationMode); } setHostBindings(tView.hostBindings); - refreshContentQueries(tView); refreshChildComponents(tView.components); } diff --git a/packages/core/test/render3/query_spec.ts b/packages/core/test/render3/query_spec.ts index 6b5f870d9e..1c5528c6a6 100644 --- a/packages/core/test/render3/query_spec.ts +++ b/packages/core/test/render3/query_spec.ts @@ -1708,12 +1708,19 @@ describe('query', () => { describe('content', () => { it('should support content queries for directives', () => { - let withContentInstance: WithContentDirective; + let withContentInstance: WithContentDirective|null = null; class WithContentDirective { // @ContentChildren('foo') foos; - // TODO(issue/24571): remove '!'. foos !: QueryList; + contentInitQuerySnapshot = 0; + contentCheckedQuerySnapshot = 0; + + ngAfterContentInit() { this.contentInitQuerySnapshot = this.foos ? this.foos.length : 0; } + + ngAfterContentChecked() { + this.contentCheckedQuerySnapshot = this.foos ? this.foos.length : 0; + } static ngComponentDef = defineDirective({ type: WithContentDirective, @@ -1746,7 +1753,18 @@ describe('query', () => { }, [WithContentDirective]); const fixture = new ComponentFixture(AppComponent); - expect(withContentInstance !.foos.length).toBe(1); + expect(withContentInstance !.foos.length) + .toBe(1, `Expected content query to match .`); + + expect(withContentInstance !.contentInitQuerySnapshot) + .toBe( + 1, + `Expected content query results to be available when ngAfterContentInit was called.`); + + expect(withContentInstance !.contentCheckedQuerySnapshot) + .toBe( + 1, + `Expected content query results to be available when ngAfterContentChecked was called.`); }); // https://stackblitz.com/edit/angular-wlenwd?file=src%2Fapp%2Fapp.component.ts