angularangular-materialangular-directiveangular18

Can we use <mat-error></mat-error> inside a *For* loop in Angular


I have created a common component. I am stuck in a problem where I am using angular material and using mat-form-field. I am using @if in angular 18 to check for a condition then mat-error is working fine. But when I am using @for it is not working and mat-error is showing inside input field not in mat-error. Also I need put my condition like this:

Above is the required format I am looking for. But I tried using single @if and @for as well. But @for is not working. Here is the output when I am using @for:

  1. First Image shows that error is coming inside a inputFor loop output when using with mat-error
@if(condition){
    @for(condition){
        <mat-error>{{error}}</mat-error>
    }
}

    <mat-form-field>
        <mat-label >{{label}}</mat-label>
            <input matInput [ngClass]="{'is-invalid': this.formGroup.get(controlName)?.invalid && this.formGroup.get(controlName)?.touched}" [formControlName]="controlName" (focus)="triggerValidation(controlName)" [required]="required" [type]="type" [placeholder]="placeholder">
                 @if(formGroup.get(controlName)?.invalid && formGroup.get(controlName)?.touched){
                     @for(error of getErrorMessages(controlName); track i; let i = $index){
                         <mat-error> {{ error }} </mat-error >
                      }
    }
    </mat-form-field>

I tried using ng-container. But for now ng-container is of no use as we have @if and @for block. I am looking for below output using @if and @else:

  1. Here is the output of my image:

Expected Output, currently I have used only @if so I am getting this output

Output which I am expecting


Solution

  • I don't know why you are doing @for for <mat-error>. You can just call getErrorMessages(controlName) within <mat-error>.

    <mat-form-field>
      <mat-label>{{label}}</mat-label>
      <input matInput [ngClass]="{'is-invalid': this.formGroup.get(controlName)?.invalid && this.formGroup.get(controlName)?.touched}"
        [formControlName]="controlName" (focus)="triggerValidation(controlName)" [required]="required" 
        [type]="type" [placeholder]="placeholder">
      @if(formGroup.get(controlName)?.invalid && formGroup.get(controlName)?.touched){
        <mat-error> {{ getErrorMessages(controlName) }} </mat-error>
      }
    </mat-form-field>
    
    

    In your getErrorMessages() function make sure you are returning error messages if a control has an error or return '' if there is no error.