deckotonic
deckotonic

Reputation: 343

Angular2: Property 'controls' does not exist on type 'AbstractControl'. Error when accessing .control of an object within a formarray thru an index

I'm trying to push another formbuilder within a formarray but it gives me an error since I think there are no items in the array when initializing the code, hence there are no controls. The error is Property 'controls' does not exist on type 'AbstractControl' after the

(<FormArray>this.loanTypeForm.controls['frequency']).controls[index]

I'm using angular 2.0.0-beta.17

let settingsForm: FormArray = new FormArray([]);
      (<FormArray>this.loanTypeForm.controls['frequency']).push(
        this.formBuilder.group({
          'name': [value, Validators.required],
          'settings': settingsForm,
        })
      );
(<FormArray>this.loanTypeForm.controls['frequency']).controls[index].controls['settings'].push(
      this.formBuilder.group({
        'term': [null, Validators.required],
        'eir': [null, Validators.required],
      })
    );

Upvotes: 34

Views: 29426

Answers (6)

Tecayehuatl
Tecayehuatl

Reputation: 310

For those still struggling(and using get keyword), you just need to strongly type your return property type. I am working with dynamic controls(FormArray).

instead:

get optionsWidgetSettingsArray(): FormArray {
    return <FormArray>this.widgetForm.get('optionsWidgetSettings');
}

use:

get optionsWidgetSettingsArray(): FormArray<FormArray<FormControl>> {
    return <FormArray>this.widgetForm.get('optionsWidgetSettings');
}

Upvotes: 0

Nuhman Pk
Nuhman Pk

Reputation: 139

Here is My solution if you are Following the Angular Course on Udemy

This code will fail with the latest Angular version. You can fix it easily though. Outsource the “get the controls” logic into a getter of your component code (the .ts file):

get controls() { // a getter!
 return (<FormArray>this.recipeForm.get(‘ingredients’)).controls;
}

In the template, you can then use:

*ngFor="let ingredientCtrl of controls; let i = index"

This adjustment is required due to the way TS works and Angular parses your templates (it doesn't understand TS there)

Upvotes: 2

jignesh patel
jignesh patel

Reputation: 9

below code is working

<FormArray>this.loanTypeForm.controls['frequency']).controls[index]['controls']['settings'].push(...)

Upvotes: 0

developer033
developer033

Reputation: 24864

You can use ['controls'] instead of .controls, as below:

(<FormArray>this.loanTypeForm.controls['frequency']).controls[index]['controls']['settings'].push(...)

But in order to simplify and provide more readability I'd suggest you to change it all to:

const control = this.loanTypeForm.get(`frequency.${index}.settings`) as FormArray;
control.push(...);

Upvotes: 90

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657058

get() is the preferred way to access form controls

this.loanTypeForm.get(`frequency.${index}.settings`)

Upvotes: 7

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123851

It seems that the loanTypeForm is treated as AbstractControl... so let's assure compiler that it is FormGroup

var group = this.loanTypeForm as FormGroup;
var array = group.controls['frequency'] as FormArray;
var control = group.controls[index]; // AbstractControl again.. could be casted as needed

and in case, that control is also group or form we just have to use assert (cast) as well

var control = group.controls[index] as FormGroup

And then we can easily continue

control.controls['settings']...

Upvotes: 6

Related Questions