Skip to content

md-error incorrect render when used with ngFor #5263

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

Closed
dimabutenko opened this issue Jun 20, 2017 · 7 comments
Closed

md-error incorrect render when used with ngFor #5263

dimabutenko opened this issue Jun 20, 2017 · 7 comments

Comments

@dimabutenko
Copy link

dimabutenko commented Jun 20, 2017

What is the expected behavior?

If I implement my component like this, it's behavior which I want

<md-input-container [formGroup]="formGroup">
                    <input mdInput [mdDatepicker]="datepicker" [formControlName]="control.name" [readOnly]="control.isReadonly"
                    [placeholder]="control.placeholder" [required]="control.isRequired">
                    <button *ngIf="!control.isReadonly" mdSuffix [mdDatepickerToggle]="datepicker"></button>
                    <md-error *ngIf="formGroup.controls[control.name].hasError('required')">Hello world</md-error>
                </md-input-container>
                <md-datepicker #datepicker></md-datepicker>

What is the current behavior?

Now I have array messages. And I have this implementation:

<md-input-container [formGroup]="formGroup">
                    <input mdInput [mdDatepicker]="datepicker" [formControlName]="control.name" [readOnly]="control.isReadonly"
                    [placeholder]="control.placeholder" [required]="control.isRequired">
                    <button *ngIf="!control.isReadonly" mdSuffix [mdDatepickerToggle]="datepicker"></button>
                    <ng-template ngFor let-errorMessage [ngForOf]="formGroup.controls[control.name].errorMessages">
                        <md-error *ngIf="formGroup.controls[control.name].hasError(errorMessage.type)">
                            {{ errorMessage.message }}
                        </md-error>
                    </ng-template>
                </md-input-container>
                <md-datepicker #datepicker></md-datepicker>

Maybe I use it incorrect. But i want to generate md-error automatically from array. I don't know what is this - new feature, bug or proposal. thanks

@willshowell
Copy link
Contributor

Here is a plunker using ngFor with md-error

http://plnkr.co/edit/VNDRcGx3DrVgYBUnqsS8?p=preview

That said, I'm not entirely certain what it is you're trying to accomplish and whether or not it is a bug.

@dimabutenko
Copy link
Author

@willshowell Can you see it? http://plnkr.co/edit/LTfzvKJUn1vGHW3N8dBE?p=preview

Error message incorrect rendering, i think.

@willshowell
Copy link
Contributor

Ah I see. I feel like this is a problem with <ng-content select="md-error"> not working well with ng-template, but I'm not sure yet.

@willshowell
Copy link
Contributor

Yeah someone with more knowledge about how transclusion works with structural directives should answer this (like @jelbourn).

I'd suggest something like this is an alternative in the mean time

http://plnkr.co/edit/MU65Gw9Dn7AvYV3R4hKB?p=preview

<md-error *ngFor="let message of currentMessages()">
  {{ message }}
</md-error>
currentMessages(): string[] {
  return this.messages
    .filter(m => this.formControl.hasError(m.type))
    .map(m => m.message);
}

@jelbourn
Copy link
Member

This is a consequence of how content project works; only the top-level elements inside the container are projected, so adding the intermediate container make it not work. Something to potentially file an issue on for Angular Core.

@alaindeurveilher
Copy link

Hi, I know this is closed, but I wanted to post my solution for those monitoring this issue. I managed to get things done by nesting <md-error> elements:

  public validationOptions: any = {
    // Messages for form validation
    messages: {
      username: [
        {validator: 'required', message: 'Please enter the username'},
        {validator: 'maxlength', message: 'The username cannot exceed 5 characters'},
        {validator: 'pattern', message: 'Only "." and alpha numeric characters are accepted'}
      ]
    }
  };
  
  private createFormControls(): void {
    this.username = new FormControl('', [
      Validators.required,
      Validators.maxLength(5),
      Validators.pattern('[a-zA-Z0-9\.]+')
    ]);
  }
<md-input-container>
  <input mdInput placeholder="Username" type="text" name="username" formControlName="username">
  <md-error *ngFor="let option of validationOptions.messages.username">
    <md-error *ngIf="username.hasError(option.validator)">{{option.message}}</md-error>
  </md-error>
</md-input-container>

which produces:
angular-material2-5263

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants