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
- 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>
- CamelCase maxLength inside .hasError(). It should be in small case
.hasError('maxlength')