Home > Back-end >  Getting error after upgrading from Angular 8 to 12 - "Property 'controls' does not ex
Getting error after upgrading from Angular 8 to 12 - "Property 'controls' does not ex

Time:09-30

I had a fully functioning code in Angular 8. I decided to upgrade from 8 to Angular 12.

I have a dynamic reactive form. The form is of question answer format. Based on who is login in the questions change. The answer is of Yes/No format. Based on who is login in and what answer option is chosen textbox dropdown and checkbox or all the there mentioned appreas.

Here is my code for the form

Component.ts

constructor(
    private router: Router,
    private datePipe: DatePipe,
    private route: ActivatedRoute,
    private formBuilder: FormBuilder) {      
    this.dynamicForm = this.formBuilder.group({
        questions: new FormArray([])
    });
    this.CreateForm();
}

get f() { return this.dynamicForm.controls; }
get t() { return this.f.questions as FormArray; }


CreateForm() {
    if (this.formdetail.questionList) {
    // CREATE Questions
    if (racialQues !==  this.formdetail.questionList[i].quetext && this.formdetail.questionList[i].quetext !== auditQues) {
      this.t.push(this.formBuilder.group({
        quesIndex: [i   1],
        ...
        controlName: [this.formdetail.questionList[i].selectedAns, [Validators.required]]
      }));
    } else if (this.formdetail.questionList[i].quetext === auditQues) {
      this.t.push(this.formBuilder.group({
        quesIndex: [i   1],
        ......
        selectedValue: [this.formdetail.auditTrail.selectedValue, this.reasonValidator],
      }));
    } else if (this.formdetail.questionList[i].quetext === racialQues) {
      
      this.t.push(this.formBuilder.group({
        quesIndex: [i   1],
        ......
        selectedAuxAns: [this.formdetail.questionList[i].val, [this.auxAnsValidator]]
      }));        
    }
}

}

Here is the html

<form [formGroup]="dynamicForm"> 
<!--  Question Start -->
<div *ngFor="let ticket of t.controls; let i = index">
    <div [formGroup]="ticket" class="form-row">  
        <div class="input-group col-md-12" style="padding: .15em .5em">                                        
            <div class="input-group-prepend col-md-10" style="padding: 0; margin: 0;">                
                <label class="input-group-text w-15">{{i   1}}</label>
                <label class="input-group-text w-100" style="text-align: left; white-space: normal;">{{ticket.controls.name.value}}</label>
            </div>                                 
            <select formControlName="controlName" class="form-control col-md-2" style="height:auto !important;" 
                [ngClass]="{ 'is-invalid': submitted && ticket.controls.controlName.errors }"
                (change)="onChange($event.target.value, i)">
                <option [ngValue]="null"> --Select-- </option>
                <option *ngFor="let ansItem of formdetail.questionList[i].answerList" [ngValue]="ansItem" >{{ansItem.anstext}}</option>
            </select>
            <div *ngIf="submitted && ticket.controls.controlName.errors" class="invalid-feedback" style="height:auto !important;" 
            [ngClass]="{ 'input-group-append': submitted && ticket.controls.controlName.errors,
                         'col-md-1': submitted && ticket.controls.controlName.errors }">
                <div *ngIf="ticket.controls.controlName.errors.required">Required</div>
            </div>
            .
            .
            .
            .
            
        </div>  
    /div>
</div>     
<!--  Question End -->                
</form>    

Now I am getting error in "ticket.control" Property 'controls' does not exist on type 'AbstractControl'. I am not sure why i am getting this error after upgrade. I have tried ticket.['control']. or ticket.get('controlName') as suggested by other article of similar error in stackoverflow but nothing works

Here is the snapshot of error

enter image description here

Any help will be appreciated. Thanks

CodePudding user response:

'controls' isn't a property of an AbstractControl. instead you can use your form group, so 'dynamicForm.controls.controlName'

CodePudding user response:

your t is of type FormArray, FormArray.controls array is of type AbstractControl[], thus, each ticket at

<div *ngFor="let ticket of t.controls; let i = index">

line is of type AbstractControl, which does not have controls property as is seen in TS error in your screenshot. TS does not know that each ticket actually is of type FormGroup (set here this.t.push(this.formBuilder.group({...}) and which has controls property).

So you can try to add another getter tControls:

get f() { return this.dynamicForm.controls; }
get t() { return this.f.questions as FormArray; }
get tControls { return this.t.controls as FormGroup[]; }

and use it within *ngFor:

<div *ngFor="let ticket of tControls; let i = index">
    <div [formGroup]="ticket" class="form-row">
    ...

Please note, that now [formGroup] will also be properly filled with FormGroup and not AbstarctControl

One of your Angular upgrades probably added

"angularCompilerOptions": {
  "fullTemplateTypeCheck": true,
  "strictInputTypes": true,
}

to your tsconfig.json file, you can verify it just by setting these values to false and rebuilding your app, but I recommend to leave these strict checks.

  • Related