Home > Software design >  How to show error message after exceeding maxLength in dynamic formArray?
How to show error message after exceeding maxLength in dynamic formArray?

Time:10-07

I have a dynamic form array, after clicking on add button I am adding dynamic fields. I am trying to use maxLength validation on one of the field of dynamic form. Technically it is working but if field is invalid I wanted to show error message.

I have tried below conditions to show error message:

    <mat-hint *ngIf="workflowAddForm.controls.runnerNodes['controls'][i].hasError('maxLength', 'script_file_content')">Max 7 characters</mat-hint>
OR
    <mat-hint *ngIf="workflowAddForm.get('runnerNodes')['controls'][i].value['script_file_content'].hasError('maxLength')">Max 7 characters</mat-hint>
OR
    <div *ngIf="script_file_content.errors?.['maxLength']">Max 7 characters</div>

But I am getting errors like hasError is not a function OR Parser Error: Unexpected token [, expected identifier or keyword at column 29 in [script_file_content.errors?.['maxLength']]

Below is my code

component.html

<form [formGroup]="workflowAddForm" >
        <div >
          <div >
            <mat-form-field  appearance="outline"  [floatLabel]="'always'" [hideRequiredMarker]="false">
              <mat-label>Name</mat-label>
              <input matInput  placeholder="Workflow Name" formControlName="workflow_name" required>
            </mat-form-field>
          </div>
        </div>

        <div >
          <ng-container formArrayName="runnerNodes" *ngFor="let nodes of workflowAddForm.get('runnerNodes')['controls']; let i = index;">
            <div  [formGroupName]="i">
              <div >
                <mat-form-field  appearance="outline"  [floatLabel]="'always'" [hideRequiredMarker]="false">
                  <mat-label>Script Name</mat-label>
                  <input matInput  placeholder="sample.py" formControlName="script_name" required>
                </mat-form-field>
              </div>

              <div >
                <mat-form-field  appearance="outline"  [floatLabel]="'always'" [hideRequiredMarker]="false">
                  <mat-label>Script file content</mat-label>
                  <textarea matInput placeholder="Script file content" formControlName="script_file_content" style="height:200px" required></textarea>
                  <!-- <mat-hint *ngIf="workflowAddForm.controls.runnerNodes['controls'][i].hasError('maxLength', 'script_file_content')">Max 7 characters</mat-hint> -->
                  <!-- <mat-hint *ngIf="workflowAddForm.get('runnerNodes')['controls'][i].value['script_file_content'].hasError('maxLength')">Max 7 characters</mat-hint> -->
                  <!-- <div *ngIf="script_file_content.errors?.['maxLength']">Max 7 characters</div> -->
                </mat-form-field>
              </div>
              <div  *ngIf="i != 0">
                <i  matTooltip="Remove" (click)="removeRunner(i)" style="color:red;">delete</i> 
              </div>
            </div>
            
          </ng-container>
          
          <div  *ngIf="runnerNodeLength !== 2"> 
            <i  matTooltip="Add Script" (click)="addMoreRunner()"  style="color: #017CAD;">add_circle_outline</i> 
          </div>
          <div >
            <div >
              <mat-form-field  appearance="outline"  [floatLabel]="'always'" [hideRequiredMarker]="false">
                <mat-label>Config File Name</mat-label>
                <input matInput  placeholder="config.json" formControlName="config_name">
              </mat-form-field>
            </div>
            <div >
              <mat-form-field  appearance="outline"  [floatLabel]="'always'" [hideRequiredMarker]="false">
                <mat-label>Config file content</mat-label>
                <textarea matInput placeholder="Config file content" formControlName="config_file_content" style="height:200px"></textarea>
              </mat-form-field>
            </div>
          </div>
        </div>

        <div >
          <div >
            <mat-form-field  appearance="outline"  [floatLabel]="'always'" [hideRequiredMarker]="false">
              <mat-label>Executer Command</mat-label>
              <input matInput  placeholder="python3 filename.py" formControlName="executer_command" required>
            </mat-form-field>
          </div>
        </div>
      </form>

component.ts

    createWorkflowAddFormBuilderObj(){
    this.workflowAddForm = this.formBuilder.group({
      workflow_name: '',
      runnerNodes: this.formBuilder.array([ this.createRunnerNode() ]),
      executer_command: '',
      config_name: '',
      config_file_content: ''
    });
  }

  createRunnerNode(): FormGroup {
    return this.formBuilder.group({
      script_name: '',
      script_file_content: ['', [Validators.required, Validators.maxLength(7)]]
    });
  }

  addMoreRunner(){
    this.runnerNodes = this.workflowAddForm.get('runnerNodes') as FormArray;
    this.runnerNodes.push(this.createRunnerNode());
    this.runnerNodeLength = this.runnerNodes.controls.length;
  }

  removeRunner(index){
    (this.workflowAddForm.get('runnerNodes') as FormArray).removeAt(index);
    this.runnerNodeLength = this.runnerNodes.controls.length;
  }

Any help is appreciated.

CodePudding user response:

You dont need to grab the reference to the control from the top form. Since you are looping through the FormArray controls in the template:

<ng-container ... *ngFor="let nodes of workflowAddForm.get('runnerNodes')['controls']; ...">

In the nodes variable you already have a reference to each node FormGroup (consider renaming the variable to node)

From there you just need to use the get()method to grab the script_file_content control and check if it has the error.

<mat-hint *ngIf="nodes.get('script_file_content').hasError('maxlength')">

Also notice that the maxlength error key is all in lowercase.

Cheers

CodePudding user response:

Two silly mistakes I did

  1. Not accessing the validator field properly. It should be like

<mat-error *ngIf="workflowAddForm.get('runnerNodes')['controls'][i].controls['script_file_content'].hasError('maxlength')">Max 7 characters</mat-error>

  1. CamelCase maxLength inside .hasError(). It should be in small case .hasError('maxlength')
  • Related