Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NG8011: Node matches the X slot of the Y component, but will not be projected into the specific slot because the surrounding @if has more than one node at its root. #54077

Open
Kerrick opened this issue Jan 25, 2024 · 10 comments
Assignees
Labels
area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime core: control flow Issues related to the built-in control flow (@if, @for, @switch)
Milestone

Comments

@Kerrick
Copy link

Kerrick commented Jan 25, 2024

Which @angular/* package(s) are the source of the bug?

compiler

Is this a regression?

Yes

Description

I have the following code which causes a warning during compilation, but the warning suggests fixes that don't apply to the code in question.

  <mat-form-field subscriptSizing="dynamic">
    <mat-label>Phone Number</mat-label>
    <input
      matInput
      [formControl]="form.controls.phoneNumber"
      required
      type="tel"
    />
    @if (form.controls.phoneNumber.hasError('isPhoneNumber')) {
      <mat-error>Must be a valid U.S. phone number</mat-error>
    }
  </mat-form-field>

This caused the following compiler warning, followed by some suggestions to fix it.

NG8011: Node matches the "mat-error, [matError]" slot of the "MatFormField" component, but will not be projected into the specific slot because the surrounding @if has more than one node at its root.

The bug here is that there is not more than one node at the root of the @if. Suggestion 1 is basically already in-place, suggestion 2 is impossible, and section 3 is already in-place.

Note that this is not a duplicate of #53477, because #53477 is a case where the content does need to be split/wrapped.

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

The compiler error is as follows:


Warning: src/app/@shared/send-it/send-it.component.html:14:7 - warning NG8011: Node matches the "mat-error, [matError]" slot of the "MatFormField" component, but will not be projected into the specific slot because the surrounding @if has more than one node at its root. To project the node in the right slot, you can:

1. Wrap the content of the @if block in an <ng-container/> that matches the "mat-error, [matError]" selector.
2. Split the content of the @if block across multiple @if blocks such that each one only has a single projectable node at its root.
3. Remove all content from the @if block, except for the node being projected.
Note: the host component has `preserveWhitespaces: true` which may cause whitespace to affect content projection.

This check can be disabled using the `extendedDiagnostics.checks.controlFlowPreventingContentProjection = "suppress" compiler option.`

14       <mat-error>Must be a valid U.S. phone number</mat-error>
         ~~~~~~~~~~~

  src/app/@shared/send-it/send-it.component.ts:15:16
    15   templateUrl: './send-it.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component SendItComponent.

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 17.1.1
Node: 18.18.0
Package Manager: yarn 1.22.19
OS: darwin arm64

Angular: 17.1.0
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, localize, material, platform-browser
... platform-browser-dynamic, router, service-worker

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1701.1
@angular-devkit/build-angular   17.1.1
@angular-devkit/core            17.1.1
@angular-devkit/schematics      17.1.1
@angular/cli                    17.1.1
@angular/pwa                    17.1.1
@schematics/angular             17.1.1
rxjs                            7.8.1
typescript                      5.3.3
zone.js                         0.14.3

Anything else?

This happens in many other similar (one root node inside the @if) instances--not always MatFormField, even--across my application.

@pkozlowski-opensource
Copy link
Member

Whitespaces count as text nodes if your application is no configured with preserveWhitespaces set to true

@Kerrick
Copy link
Author

Kerrick commented Jan 25, 2024

I have a particular need for preserveWhitespaces to be set to true in my case. The compiler warning doesn't instruct me how I should or should not format the whitespace in/around the @if block if I want to prevent the content projection problem while keeping "preserveWhitespaces": true in my config.

@jessicajaniuk jessicajaniuk added the area: compiler Issues related to `ngc`, Angular's template compiler label Jan 25, 2024
@ngbot ngbot bot added this to the needsTriage milestone Jan 25, 2024
@jessicajaniuk
Copy link
Contributor

You can remove the whitespace inside the @if block to solve this problem.

@pkozlowski-opensource pkozlowski-opensource added core: control flow Issues related to the built-in control flow (@if, @for, @switch) area: core Issues related to the framework runtime labels Jan 25, 2024
@crisbeto
Copy link
Member

The warning mentions that the component has preserveWhitespaces: true. See this line:

Note: the host component has preserveWhitespaces: true which may cause whitespace to affect content projection.

@Kerrick
Copy link
Author

Kerrick commented Jan 26, 2024

The warning mentions that the component has preserveWhitespaces: true. See this line:

Note: the host component has preserveWhitespaces: true which may cause whitespace to affect content projection.

It does not, however, suggest a way to fix the problem while maintaining preserveWhitespace: true. Nor does it explain why or how white space affects content projection. Nor does it explain that text nodes are relevant at all. Perhaps this is less a compiler bug, and more of a compiler developer experience problem.

@JelleBruisten
Copy link
Contributor

@Kerrick can you issue be resolved by using ngPreserveWhitespaces where you specifically need to preserve whitespaces? Or is your usecase application wide?

@Lavos96
Copy link

Lavos96 commented Mar 1, 2024

I have, same problem, it was working fine with old *ngFor in my scenario.

@Kerrick
Copy link
Author

Kerrick commented Mar 25, 2024

For additional context, see Caveat 2 mentioned in this commit which is related to #52277.

@raknjarasoa
Copy link

The suggested workaround form the warning message work well for me.
The snippets below should work:

<mat-form-field subscriptSizing="dynamic">
  <mat-label>Phone Number</mat-label>
  <input
    matInput
    [formControl]="form.controls.phoneNumber"
    required
    type="tel"
  />
  <ng-container ngProjectAs="mat-error"> <!-- Or for attribut <ng-container matError>   -->
    @if (form.controls.phoneNumber.hasError('isPhoneNumber')) {
      <mat-error>Must be a valid U.S. phone number</mat-error>
    }
  </ng-container>
</mat-form-field>

@Chuli2k
Copy link

Chuli2k commented May 26, 2024

So is there a way to use preserveWhitespaces=true and not have this warning? I don't understand why whitespaces could interfere with content projection...
Also using the solution from @raknjarasoa seems a bit overkill to use for every error in my application.

Edit: Read the Caveat 2 in the commit. Guess this will stay and we'll have to live with it...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime core: control flow Issues related to the built-in control flow (@if, @for, @switch)
Projects
None yet
Development

No branches or pull requests

8 participants