question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[ivy] ContentChildren doesn't pick up elements inside ng-container

See original GitHub issue

🐞 bug report

Affected Package

The issue is caused by package @angular/core@9.0.0-rc.8

Is this a regression?

Yes, the previous version in which this bug was not present was: v8

Description

ContentChildren doesn’t pick up things marked with ngProjectAs.

<app-parent name="indirect with projectAs">
  <ng-container *ngFor="let i of [1, 2, 3, 4]" ngProjectAs="app-child">
    <app-child>
      {{ i }}
    </app-child>
  </ng-container>
</app-parent>
...
export class ParentComponent {
  @ContentChildren(ChildComponent, { descendants: false }) children: QueryList<
    ChildComponent
  >;
}

In v8, the ContentChildren in the ParentComponent would pick up the app-child inside the ng-container (technically, it did this regardless of ngProjectAs, but the point is it did work). In Ivy, it no longer picks up the children with or without an ngProjectAs. Given <ng-content select=*> does work with ngProjectAs, it seems to me that ContentChildren should as well.

🔬 Minimal Reproduction

https://github.com/henry-alakazhang/angular-content-children-repro Master branch is v9, v8 branch is v8. https://github.com/henry-alakazhang/angular-content-children-repro/tree/v8

🌍 Your Environment

Angular Version:


Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.0-rc.8
@angular-devkit/build-angular     0.900.0-rc.8
@angular-devkit/build-optimizer   0.900.0-rc.8
@angular-devkit/build-webpack     0.900.0-rc.8
@angular-devkit/core              9.0.0-rc.8
@angular-devkit/schematics        9.0.0-rc.8
@angular/localize                 9.0.0-rc.0
@ngtools/webpack                  9.0.0-rc.8
@schematics/angular               9.0.0-rc.8
@schematics/update                0.900.0-rc.8
rxjs                              6.5.4
typescript                        3.6.4
webpack                           4.41.2

Anything else relevant? Related to #34289, but the suggested solution (descendants: true) is not always feasible. In my case, I want to be able to nest another parent inside the child and using descendants: true would pick up the nested children as well.

Similarly, the other suggestion in the compatibility guide, to only use direct descendants, is difficult to use if I want to apply multiple structural directives to the child, eg.

<app-parent>
  <ng-container *ngFor="...">
    <app-child *ngIf="...">
  </ng-container>
</app-parent>

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:6
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
crisbetocommented, Jan 14, 2020

From what I can tell the issue isn’t due to ngProjectAs, but as you mentioned, that you have an extra ng-container between the parent and the child.

1reaction
pkozlowski-opensourcecommented, Jan 14, 2020

@henry-alakazhang as commented by @crisbeto I believe that ngProjectAs attribute is not relevant here (and I’ve changed the title accordingly). What matters here is the presence of <ng-container> that, with ngIvy, acts as any regular element (wrt the descendants option for queries). In this sense this is a known breaking change in Angular + ngIvy.

Having said this, it is very easy to get the correct behaviour without using <ng-container> (which, btw, would be slightly more performant and would result in less generated code => smaller bundles).

Given your first example you could do (shorter and ngProjectAs might not be needed at all!):

<app-parent name="indirect with projectAs">
    <app-child *ngFor="let i of [1, 2, 3, 4]" >
      {{ i }}
    </app-child>
</app-parent>

If you want to have a group of sibling elements then you can use the de-sugared version of ngIf / ngFor:

<app-parent>
  <ng-template ngFor="..." [ngForOf]="...">
    <app-child *ngIf="...">
  </ng-template>
</app-parent>

Queries with descendants: false will work correctly in both VE and ivy using the above forms. @henry-alakazhang could you give it a try and let me know if this works for you? Thnx!

We are still debating what to do with <ng-container> and queries but as of today the solution outlined above is the best approach.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular @ContentChildren doesn´t work with <ng-template>
This doesn't work because of rendering the tree from a template. It appears that when wrapping the component in a ng-template , @ContentChildren...
Read more >
angular/core
Implements Angular's core functionality, low-level services, and utilities. Defines the class infrastructure for components, view hierarchies, ...
Read more >
Heading Off 11 Common Angular Application Design, Best ...
The Angular ng-container element is another element that doesn't represent anything in the DOM, but it's contents are always rendered.
Read more >
Agnostic components in Angular - InDepth.Dev
This is a dynamic instrument but it doesn't interpolate into HTML. ... To make a reusable piece of layout Angular has ng-template. With...
Read more >
ngx-dynamic-hooks - npm
Automatically insert live Angular components into a dynamic string of ... with an out-of-the-box SelectorHookParser that is easy to set up.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found