angulartypescriptangular-validationangular-validator

Validation not working on fields name ending with dots in angular


I'm creating dynamic fields

<input class="form-control-lg form-control" placeholder="{{data.DisplayName}}" formControlName="{{data.labelName}}" type="text"  maxlength="13">

this.fieldsData.forEach((ele, i) => {
  form[ele?.labelName]=new FormControl('',ele?.mandatory=='yes' ? Validators.required : []);
  this.FormGroup=new FormGroup(form);
..
}

on my HTML component displays an error message like this

 <div *ngIf="FormGroup.get(data.labelName) as control"> <div *ngIf="(control.touched || control.dirty) && (!control.valid)"> <p class="errorMsg" *ngIf="control.errors.required">This field is required</p>  <p class="errorMsg" *ngIf="control.errors.pattern">Please provide a valid email address</p>     </div> </div>

The issue is when the dot is there in the end in the field name validation is working but the error message is not shown.


Solution

  • You can solve this error by using a different method of accessing the control. Obviously the problem is the dot. We can use the dynamic access method and using controls instead of getControl.

    getControl(labelName: string) {
      return this.FormGroup.controls[labelName];
    }
    

    Full Code:

    import { Component } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import {
      FormBuilder,
      ReactiveFormsModule,
      FormControl,
      FormGroup,
      Validators,
    } from '@angular/forms';
    import 'zone.js';
    import { CommonModule } from '@angular/common';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [CommonModule, ReactiveFormsModule],
      template: `
        <form [formGroup]="FormGroup">
                <div *ngFor="let data of fieldsData">
                <ng-container [ngSwitch]="data.inputType">
                  <ng-container *ngSwitchCase="'dropdown'">
                    <select name="cars" id="cars">
                      <option value="volvo">Volvo</option>
                      <option value="saab">Saab</option>
                      <option value="mercedes">Mercedes</option>
                      <option value="audi">Audi</option>
                    </select>
                  </ng-container>
                  <ng-container *ngSwitchCase="'textbox'"><textarea [formControlName]="data.labelName"></textarea></ng-container>
                  <ng-container *ngSwitchDefault><input type="text" [formControlName]="data.labelName"></ng-container>
                
                  
    
    
                </ng-container>
                <div *ngIf="FormGroup.get(data.labelName) as control" class="checkValue"> <div *ngIf="(control.touched || control.dirty) && (!control.valid)"> <p class="errorMsg" *ngIf="control.errors?.['required']">This field is required</p>  <p class="errorMsg" *ngIf="control.errors.pattern">Please provide a valid email address</p>     </div> </div>
                <label>{{data.labelName}} </label>
                
                </div>
                <button class="btn-submit" type="button" [disabled]="!FormGroup.valid" style="margin-top: 20px" (click)="SubmitDemo()">
                    Submit
                </button>
        </form>
      `,
    })
    export class App {
      fieldsData = [
        {
          labelName: 'Name',
          inputType: 'textbox',
          inputValues: '',
          mandatory: 'yes',
        },
        {
          labelName: 'contact no.',
          inputType: 'textbox',
          inputValues: '',
          mandatory: 'yes',
        },
        {
          labelName: 'address 2',
          inputType: 'textarea',
          inputValues: null,
          mandatory: 'yes',
        },
      
      ];
      FormGroup!: FormGroup;
    
      ngOnInit() {
        const form: any = {};
        this.fieldsData.forEach((ele, i) => {
          const validators = ele?.mandatory === 'yes' ? [Validators.required] : [];
          form[ele?.labelName] = new FormControl('', validators);
        });
        this.FormGroup = new FormGroup(form);
      }
    
      SubmitDemo() {}
    }
    
    bootstrapApplication(App);
    

    Stackblitz Demo