components: [form-field] add md-error-container directive to content projection

Bug, feature request, or proposal:

Proposal

Currently

If a user wishes to surround MdErrors with a structural directive, the errors will no longer be projected inside the mat-input-subscript-wrapper.

<!-- This will not work -->
<md-form-field>
  <input mdInput>
  <ng-container *ngFor="let error of allErrors">
    <md-error *ngIf="showError(error)">{{error.message}}</md-error>
  </ng-container>
</md-form-field>

This is (sort of) expected behavior if you know that content projection works only on top level elements. Still, if you want to conditionally render your errors with ngFor and ngIf you have to use one of the workarounds (listed under Motivation).

Proposed

<!-- This could work -->
<md-form-field>
  <input mdInput>
  <md-error-container *ngFor="let error of allErrors">
    <md-error *ngIf="showError(error)">{{error.message}}</md-error>
  </md-error-container>
</md-form-field>
<!-- form-field.html -->
...

<div *ngSwitchCase="'error'" [@transitionMessages]="_subscriptAnimationState">
  <ng-content select="md-error, md-error-container"></ng-content>
</div>

Reproduction

This is an example showing how it could work

http://plnkr.co/edit/6c6Zi6m1dNAnF10smWPK?p=preview

Motivation

Couple of issues bringing this up

https://github.com/angular/material2/issues/5263 https://github.com/angular/material2/issues/5292

Workarounds:

https://github.com/angular/material2/issues/5263#issuecomment-309915318 https://github.com/angular/material2/issues/5263#issuecomment-324671153

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 18 (17 by maintainers)

Most upvoted comments

@willshowell, I do not remember where I found it, but you can use, as an acceptable workaround, the ngProjectAs (sorry if maybe I’m not getting right the big picture here):

<md-form-field>
  <input mdInput>
  <ng-container *ngFor="let error of allErrors" ngProjectAs="md-error">
    <md-error *ngIf="showError(error)">{{error.message}}</md-error>
  </ng-container>
</md-form-field>

I will look for the reference where I got this.

Edited: just found it => https://medium.com/claritydesignsystem/ng-content-the-hidden-docs-96a29d70d11b

Plunk: http://plnkr.co/edit/pmJbQMFMtNqFEbLRZAdP?p=preview

Anyway, it doesn’t look like this so not-documented ngProjectAs is something that should be expected to be used by the developers in day-by-day coding as it demands some knowledge on how the target component works on the inside (in this case, the md-form-field selector).

I think there may be a bug in core. This shows all 4 errors (3 from app-form-validation):

  <md-form-field>
    <input mdInput [formControl]="myControl" required>
    <app-form-validation ngProjectAs="md-error"></app-form-validation>
    <ng-container ngProjectAs="md-error">
      <md-error>This field is required</md-error>
    </ng-container>
  </md-form-field>

http://plnkr.co/edit/2VqnymNAkTzRCOyK0dT1?p=preview

…while (as demoed), this doesn’t show any:

  <md-form-field>
    <input mdInput [formControl]="myControl" required>
    <app-form-validation ngProjectAs="md-error"></app-form-validation>
  </md-form-field>