Components: <mat-error> not usable when instantiated inside <ng-template>

Created on 28 Oct 2017  路  9Comments  路  Source: angular/components

Bug, feature request, or proposal:

Bug

What is the expected behavior?

It should be possible to use an ng-template with mat-error inside it to create a reusable error display template.

What is the current behavior?

When mat-error is included as part of an ng-template it is not rendered correctly.

What are the steps to reproduce?

StackBlitz starter (using latest npm release): https://stackblitz.com/edit/angular-jpmbve

<ng-template #errTempl let-ctl>
  <mat-error *ngIf="ctl.hasError('pattern')">test2</mat-error>
</ng-template>
<form novalidate [formGroup]="theForm">
  <mat-form-field>
    <mat-select placeholder="Platform (bugged)" formControlName="platform">
      <mat-option value="WST">WST</mat-option>
      <mat-option value="FTD">FTD</mat-option>
    </mat-select>
    <ng-template [ngTemplateOutlet]="errTempl"
                 [ngOutletContext]="{ $implicit: theForm.controls['platform'] }"></ng-template>
  </mat-form-field>
</form>

Note how the mat-error element is instantiated inside the ng-template - doing it this way causes the mat-error text to be displayed incorrectly.

What is the use-case or motivation for changing an existing behavior?

The use case is having a reusable error display template that can be attached to different fields with the same error logic.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular: 4.4.6
Angular animations: 4.4.6
Typescript: 2.5.3
Browser: Chrome 62.0.3202.75 (Official Build) (64-bit)

Is there anything else we should know?

All 9 comments

Try this:

    <ng-template ngProjectAs="mat-error" [ngTemplateOutlet]="errTempl"
                 [ngOutletContext]="{ $implicit: theForm.controls['platform'] }"></ng-template>

@julianobrasil I tried that, now the error message in the template is not displayed at all. See the updated stackblitz https://stackblitz.com/edit/angular-v6nvbn

I really don't know whether this is a problem with angular or with material or with my undertanding of how some stuff works. This is similar to this other closed-without-complete-solution issue #6625

It starts working if you use an empty <mat-error></mat-error> together with ngProjectAs. I don't have a plausible explanation for that. See your modified stackblitz: https://stackblitz.com/edit/angular-wcedma?file=app/app.component.html

@julianobrasil thanks for the effort, I will use this workaround for now I guess. So do we just let this issue be and wait for it to get resolved by the way?

@jelbourn, do you think this could be a material issue? It's similar to this other: #6625. By that time it was closed just because the original problem seemed to be solved. But there were cases without a solution in that issue. The most accepted theory was about an angular issue.

cc: @rafaelss95

This is the expected behavior of Angular. ng-template creates an inert template that can be grabbed and stamped out elsewhere. The content of the template does not "exist" in the view. Components like form-field need their content children to "exist" in order to see them.

@jelbourn Having said all that, is it still ok to do what I have done? Meaning - to create an ng-template definition with mat-error elements inside it and stamp it inside mat-form-field elements across my form while using the workaround mentioned by @julianobrasil - i.e. placing an empty mat-error next to each instance of ng-template

If that works then it should be fine

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xtianus79 picture xtianus79  路  3Comments

jelbourn picture jelbourn  路  3Comments

Hiblton picture Hiblton  路  3Comments

theunreal picture theunreal  路  3Comments

LoganDupont picture LoganDupont  路  3Comments