Dilanka Rathnayake Dilanka Rathnayake - 13 days ago 10
HTML Question

Validating *ngFor used forms using angular 2 [formControl]

I have an angular Form and it used

*ngFor
for repeat an input box. Also, I have to validate dynamically all input boxes that are generated by
*ngFor
.

There is a JSON array called list that contains Questions. and I have to generate input boxes for answers and they should be validated. Validation information also in the list.

This is an example of the list

[{id:1,
mandatory:false,
questionDescription:"Blue flags are in position and contain words “Stop, Tank Car Connected” or “Stop, Men at Work”",
questionType:1,
validation:{maximum:100,minimum:0}},
{id:2,
mandatory:true,
questionDescription:"Wheels are chocked and handbrake(s) set” or “Stop, Men at Work",
questionType:2,
validation:{maxLength:10,minLength:3}}]


I tried to validate generated input boxes as described in here.
https://scotch.io/tutorials/angular-2-form-validation (see validation forms there).

So I have to give validation information for each input boxes like below.
(this example from given tutorial)

constructor(fb: FormBuilder){
this.complexForm = fb.group({
'firstName' : [null, Validators.required],
'lastName': [null, Validators.compose([Validators.required, Validators.minLength(5), Validators.maxLength(10)])]
})


this is the HTML for it.

<div class="form-group">
<label>First Name:</label>
<input class="form-control" type="text"[formControl]="complexForm.controls['firstName']">
</div>
<div class="form-group" >
<label>Last Name</label>
<input class="form-control" type="text" [formControl]="complexForm.controls['lastName']">
</div>


So in my case, all input boxes generate by
*ngFor
and I have to assign tags like
firstName
,
lastName
dynamically to those boxes.
So I used
question.id
as that tag and implemented control group as followed.

inspectionForm: FormGroup;

constructor(fb: FormBuilder) {

this.questionTemplate = templateService.getQuestionTemplate();

let objString: string = "{";

for (let item of this.questionTemplate.sectionList[0].questionList) {
if (item.questionType == 2) {
objString += '"' + item.id + '":null,';
}
}

objString = objString.slice(0, -1);
objString += '}';
let objJson = JSON.parse(objString);

for (let item of this.questionTemplate.sectionList[0].questionList) {
if (item.questionType == 2) {
objJson[item.id] = [null,Validators.compose([Validators.minLength(item.validation.minLength), Validators.maxLength(item.validation.maxLength)])];
}
}
this.inspectionForm = fb.group(objJson);
}


and here is my HTML code.

<form [formGroup]="inspectionForm" (ngSubmit)="submitForm(inspectionForm.value)">

<div *ngFor="let question of section.questionList" [ngSwitch]="question.questionType">
<ion-row *ngSwitchCase="QuestionType.String">
<ion-col width-80>{{question.questionDescription}}</ion-col>
<ion-col width-20>
<ion-input id="{{question.id}}" type="text" class="inspection-bottom-border" [formControl]="inspectionForm.controls['{{question.id}}']"></ion-input>
</ion-col>
</ion-row>
</div>

<div class="form-group">
<button type="submit" class="btn btn-primary" [disabled]="!inspectionForm.valid">Submit</button>
</div>

</form>


The Problem is....

If I define
[formControl]
as
[formControl]="inspectionForm.controls['{{question.id}}']"


I get an error like follows,

unhandled Promise rejection: Template parse errors:
Parser Error: Got interpolation ({{}}) where expression was expected at column 25 in [inspectionForm.controls['{{question.id}}']] in InspectionPage@36:91 ("idth-20>
<ion-input id="{{question.id}}" type="text" class="inspection-bottom-border" [ERROR ->][formControl]="inspectionForm.controls['{{question.id}}']"></ion-input>


then I searched for an answer in StackOverflow, I found someone has said don't use
[]
and
{{}}
in one time (Dynamic routerLink value from ngFor item giving error "Got interpolation ({{}}) where expression was expected")

But if I removed
[]
and defined as follows

formControl="inspectionForm.controls['{{question.id}}']"


I get an error as follows

EXCEPTION: Error in ./InspectionPage class InspectionPage - inline template:36:91 caused by: Cannot create property 'validator' on string 'inspectionForm.controls['2']'


(this '2' the is question.id of first type 2 question)

if I define as follows same error occurs

formControl="inspectionForm.controls['2']"


But the problem is if I define as follows with
[formControl]


[formControl]="inspectionForm.controls['2']"


The app is Working Perfectly....

But I have to give
question.id
dynamically. How I can do that?

Are there someone have a solution for this error. Please give a suggestion.

Thank you very much.

Answer

just use [formControl]="inspectionForm.controls[question.id]"

Thanks @Sasxa for the answer

Comments