Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Property 'controls' does not exist on type 'AbstractControl'. #6099

Closed
shammelburg opened this issue Apr 27, 2017 · 36 comments

Comments

Projects
None yet
@shammelburg
Copy link

commented Apr 27, 2017

Bug Report or Feature Request (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request

Versions.

@Angular/cli: 1.0.1
node: 7.5.0
os: win32 x64
Windows (10)

Repro steps.

Running the application using ng serve works fine.

using ng build works fine.

when using ng build --prod --aot or ng build --prod I get the error.

It points back to this html file and the controls property??

<div formArrayName="Data">
    <div class="form-group" *ngFor="let field of form.get('Data').**controls**; let i = index">
        <div [formGroupName]="i">
            <div class="col-sm-2">
                <input type="text" class="form-control input-sm text-right" placeholder="Key" formControlName="Name" />
            </div>
            <div class="col-sm-6">
                <input type="text" class="form-control input-sm" placeholder="Value" formControlName="Data" autocomplete="off" />
            </div>
            <div class="col-sm-1">
                <i class="fa fa-trash-o cursor remove-field" title="Remove field" (click)="removeField(i)"></i>
            </div>
        </div>
    </div>
</div>

The log given by the failure.

ERROR in ng:///C:/Angular/lanes4/src/app/containers/edit-user.component.html (34,13): Property 'controls' does exist on type 'AbstractControl'.

Desired functionality.

I would like to build it using --prod and --aot

Mention any other details that might be useful.

Happened since updating to version 4.0.0, i've just been using ng build

@Thisen

This comment has been minimized.

Copy link

commented Apr 28, 2017

Can be fixed by giving your component a get method:
get formData { return this.form.get('Data'); }
and then in your template:
<div class="form-group" *ngFor="let field of formData.controls; let i = index">

@shammelburg

This comment has been minimized.

Copy link
Author

commented May 2, 2017

@Thisen, It works with ng s but I am still getting the same error when building using either ng build --prod or ng build --prod --aot.

Property 'controls ' does not exist on type 'AbstractControl'.

Thank you

@shammelburg

This comment has been minimized.

Copy link
Author

commented May 2, 2017

Got it!

Looked at the docs - FormArray

The FormArray class contains the controls property.

get formData() { return <FormArray>this.passwordForm.get('Data'); }

Thanks @Thisen, without you help it would've taken longer.

@shammelburg shammelburg closed this May 2, 2017

@zpydee

This comment has been minimized.

Copy link

commented May 15, 2017

I'm experiencing the same issue when trying to run ng build --prod with the snippet below although it seems my circumstance is a bit different. Not seeing this occur on any of my other forms?

Can either of your offer any guidance? I'm also running 4.0.0.

<form id="reset-password-form" novalidate [formGroup]="form" (ngSubmit)="submitForm()">
  <div fxLayout fxLayoutWrap>
    <!-- Current Password -->
    <div fxFlex="50%" fxFlex.xs="100%">
      <md-input-container id="currentPassword-container" class="full-width">
        <md-placeholder>Current Password</md-placeholder>
        <input id="currentPassword" mdInput required type="password" formControlName="currentPassword">
        <md-hint align="end" *ngIf="form.controls.currentPassword.dirty && form.controls.currentPassword.errors?.required">Current password is required</md-hint>
        <md-hint align="end" *ngIf="form.controls.currentPassword.dirty && form.controls.currentPassword.errors?.pattern">Must contain 8-16 characters, letters and numbers and symbols</md-hint>
      </md-input-container>
    </div>
    <div fxFlex="50%" fxFlex.xs="100%"></div>
    <div fxFlex="100%" fxLayout fxLayoutWrap formGroupName="passwords">
      <!-- New Password -->
      <div fxFlex="50%" fxFlex.xs="100%">
        <md-input-container id="password-container" class="full-width">
          <md-placeholder>New Password</md-placeholder>
          <input id="password" mdInput required type="password" formControlName="password">
          <md-hint align="end" *ngIf="form.controls.passwords.controls.password.dirty && form.controls.passwords.controls.password.errors?.required">New password is required</md-hint>
          <md-hint align="end" *ngIf="form.controls.passwords.controls.password.dirty && form.controls.passwords.controls.password.errors?.pattern">Must contain 8-16 characters, letters and numbers and symbols</md-hint>
        </md-input-container>
      </div>
      <div fxFlex="50%" fxFlex.xs="100%"></div>
      <!-- Confirm Password -->
      <div fxFlex="50%" fxFlex.xs="100%">
        <md-input-container id="confirmPassword-container" class="full-width">
          <md-placeholder>Confirm New Password</md-placeholder>
          <input id="confirmPassword" mdInput required type="password" formControlName="confirmPassword">
          <md-hint align="end" *ngIf="form.controls.passwords.controls.confirmPassword.dirty && form.controls.passwords.controls.confirmPassword.errors?.required">Password confirmation is required</md-hint>
          <md-hint align="end" *ngIf="form.controls.passwords.controls.confirmPassword.dirty && !form.controls.passwords.controls.confirmPassword.errors?.required &&form.controls.passwords.errors?.passwordMismatch">Passwords do not match</md-hint>
        </md-input-container>
      </div>
      <div fxFlex="50%" fxFlex.xs="100%"></div>
    </div>
  </div>
  <div fxLayout fxLayoutAlign="center">
    <!--Action buttons-->
    <button md-raised-button type="submit" [disabled]="!form.valid">RESET PASSWORD</button>
  </div>
</form>
ERROR in ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (22,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (22,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (22,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (23,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (23,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (23,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (32,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (32,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (32,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (33,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (33,11): Property 'controls' does not exist on type 'AbstractControl'.
ng:///usr/mystique/src/app/features/main/core-features/user-settings/reset-password/reset-password.component.html (33,11): Property 'controls' does not exist on type 'AbstractControl'.
@zpydee

This comment has been minimized.

Copy link

commented May 15, 2017

so, my issue was solved by changing the way controls were referenced in my <md-hint> blocks

changed to form['controls'].passwords['controls'].confirmPassword.dirty.

can anyone expand one why this is necessary with forms? is it because of the change detection cycle? I find it quite curious that the error was only ocurring on one of my form when the pattern I was using was consistent all forms...

@Yura13

This comment has been minimized.

Copy link

commented Jun 1, 2017

This problem still present.
If use form.get('Data').controls inside *ngFor and run ng build --prod, you will see error:
Property 'controls' does not exist on type 'AbstractControl'.

Angular CLI: 1.0.6
Angular: 4.1.3
node: 6.10.3

tom-power added a commit to tom-power/gear-inch-calculator that referenced this issue Jul 12, 2017

@dgroh

This comment has been minimized.

Copy link

commented Aug 3, 2017

I can confirm this.

when using --prod the HTML fails:

Property 'controls' does not exist on type 'AbstractControl'.

For now, I'm usin workaround of passing the logic to the ts, but it's not good because it's a public method.

@ghost

This comment has been minimized.

Copy link

commented Aug 5, 2017

version: Angular 4
@angular/cli: 1.2.1
node: 8.2.1
os: darwin x64

I can run the program on localhost: 4200. When ng build -- prod --aot, I get the following error:
Property 'controls' does not exist on type 'AbstractControl'.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from "@angular/router";
import { FormGroup, FormControl, FormArray, Validators } from "@angular/forms";
import { RecipeService } from "app/recipes/recipe.service";
import { Recipe } from "app/recipes/recipe.model";

@component({
selector: 'app-recipe-edit',
templateUrl: './recipe-edit.component.html',
styleUrls: ['./recipe-edit.component.css']
})
export class RecipeEditComponent implements OnInit {
id: number;
editMode = false;
recipeForm: FormGroup;

constructor(private route: ActivatedRoute,
private recipeService: RecipeService,
private router: Router) { }

ngOnInit() {
this.route.params.subscribe(
(params: Params) => {
this.id = +params['id'];
this.editMode = params['id'] != null;
this.initForm();
// console.log(this.editMode);
}
);
}
onSubmit() {
const newRecipe = new Recipe(
this.recipeForm.value['name'],
this.recipeForm.value['description'],
this.recipeForm.value ['imagePath'],
this.recipeForm.value ['ingredients']);

if (this.editMode) {
  this.recipeService.updateRecipe(this.id, newRecipe);
}
else {
  this.recipeService.addRecipe(newRecipe);
}

}

onClickX(index: number) {
(this.recipeForm.get('ingredients')).removeAt(index);
}

onClickCancel(){
this.router.navigate(['../'], {relativeTo: this.route})
}
onClickAddIngredient() {
(this.recipeForm.get('ingredients')).push(new FormGroup({
'name': new FormControl(null, Validators.required),
'amount': new FormControl(null,
// [Validators.required,
// Validators.pattern(/'^[1-9]+[0-9]*$'/)]
)
})
);
}
private initForm() {
let recipeName = '';
let recipeImagePath = '';
let recipeDescription = '';
let recipeIngredients = new FormArray([]);

if(this.editMode) {
const recipe = this.recipeService.getRecipe(this.id);
  recipeName = recipe.name;
  recipeImagePath = recipe.imagePath;
  recipeDescription = recipe.description;
  if(recipe['ingredients']) {
    for(let ingredient of recipe.ingredients) {
      recipeIngredients.push(
      new FormGroup({
        'name': new FormControl(ingredient.name, Validators.required),
        'amount': new FormControl(ingredient.amount, [
          Validators.required,
          // Validators.pattern(/'^[1-9]+[0-9]*$'/)
        ])
      })
    );
    }
  }
}
this.recipeForm =  new FormGroup({
  'name': new FormControl(recipeName, Validators.required),
  'imagePath': new FormControl(recipeImagePath, Validators.required),
  'description': new FormControl(recipeDescription, Validators.required),
  'ingredients': recipeIngredients
});

}
}

I am using 'get'. Can anyone help? Any suggestions?
Thank you.

@gzoppo

This comment has been minimized.

Copy link

commented Sep 7, 2017

La solucion mas facil es: formGroup.controls['any']['controls'].

@ghost

This comment has been minimized.

Copy link

commented Sep 7, 2017

Thank you!!

@Sevensnake

This comment has been minimized.

Copy link

commented Oct 4, 2017

Having the same problem. ERROR in ng:///C:/Web/src/app/part-d-table/Modules/d8-tables/d8-tables.component.html (129,81): Property 'PercentVal' does not exist on type 'any[]'. ERROR in ng:///C:/Web/src/app/dashboard/dashboard.component.html (25,30): Property 'center' does not exist on type boardComponent'. ERROR in ng:Web/src/app/column-a-table/column-a-table.component.html (12,40): Property 'refresh' does not exist on type 'ColumnTableComponent'

@Sevensnake

This comment has been minimized.

Copy link

commented Oct 4, 2017

But works when I use ng build

@souflam

This comment has been minimized.

Copy link

commented Oct 18, 2017

thnks @zpydee , this solution worked for me:
i used myForm['controls'].links['controls'] instead of myForm.controls.links.controls

@cdCarlos

This comment has been minimized.

Copy link

commented Nov 17, 2017

What works for me (even using --prod flag) is, instead of using controls in the FormArray I use value:
*ngFor="let item of myForm.get('items').value"

@gabpa3

This comment has been minimized.

Copy link

commented Dec 9, 2017

formGroupName.controls['attributeName'] works for me

@anandchakru

This comment has been minimized.

Copy link

commented Jan 22, 2018

In my case only ng build --prod --aot was failing with Property 'controls' does not exist on type 'AbstractControl'

I changed

<div *ngFor="let arr_item of myForm.controls['some_items'].controls;let indx=index;let lst=last;" class="input-group"> 

to

<div *ngFor="let js_arr_item of getControls(myForm, 'some_items');let indx=index;let lst=last;" class="input-group">

&

getControls(frmGrp: FormGroup, key: string) {
  return (<FormArray>frmGrp.controls[key]).controls;
}

turns out, its yet another "cast" issue (pun intended) ;-)

@acharyaks90

This comment has been minimized.

Copy link

commented Feb 1, 2018

Thanks @shammelburg souflam
Solution worked for me

@leandrodiniz

This comment has been minimized.

Copy link

commented Feb 24, 2018

change:
myForm.get('some_items').controls

to:
myForm.get('some_items')['controls'];

worked for me when using --prod

@6matko

This comment has been minimized.

Copy link

commented Feb 24, 2018

Did the same as @leandrodiniz and it also worked with --env=prod --aot.

@Karthey

This comment has been minimized.

Copy link

commented Mar 1, 2018

Hi, I am using an abstract control in the form which has child component.
For some reason the child inputs get disabled. I am trying to keep it enabled all the time.

Not sure what I am doing wrong. :(

tried: this.paymentMethodForm.controls['card-number'].disable({ emitEvent: false }); --NOT working---

`import { Component, Input, Output, EventEmitter, OnChanges } from '@angular/core';
import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
import { System } from '../system';
import { BillingAndPaymentsService } from './billing-payments.service'
import { PaymentMethod } from './payment-methods'

export abstract class AddPaymentMethodComponent implements OnChanges {
@input() system: System;
@input() paymentMethod: PaymentMethod;
@input() alwaysSave = false;
@input() isCancelable = false;
@output() saved = new EventEmitter();
@output() canceled = new EventEmitter();
@input() isActive = true;

paymentMethodForm: FormGroup;
showError: boolean = false;
isLoading: boolean = false;

constructor(protected fb: FormBuilder, protected billingAndPaymentsService: BillingAndPaymentsService, controlsConfig: { [key: string]: any; }, extra?: { [key: string]: any; }) {
    controlsConfig = Object.assign(controlsConfig,
        {
            useInstallationAddress: [false],
            save: [this.alwaysSave],
            address: this.fb.group({
                street: ['', Validators.required],
                city: ['', [Validators.required, Validators.maxLength(40)]],
                state: ['', Validators.required],
                zip: ['', [Validators.required, Validators.maxLength(20)]]
            })
        });
    this.paymentMethodForm = this.fb.group(controlsConfig);
    
}

abstract patchPaymentMethodForm(paymentMethod: PaymentMethod): void;

toggleAddressControls() {
   //  this.paymentMethodForm.get('card-number').enable();
    if (this.paymentMethodForm.get('useInstallationAddress').value)
        this.paymentMethodForm.get('address').disable();
    else
        this.paymentMethodForm.get('address').enable();
}

onSubmit(paymentMethod: PaymentMethod) {
    if (this.paymentMethod)
        Object.assign(paymentMethod, this.paymentMethod);

    paymentMethod.isHidden = !this.paymentMethodForm.get('save').value;

    if (this.paymentMethodForm.get('useInstallationAddress').value) {
        const installationAddress = this.system.installationAddressLine2
            ? (this.system.installationAddressLine1 + ', ' + this.system.installationAddressLine2)
            : this.system.installationAddressLine1; // Create installation address line, check if line 2 is null
        paymentMethod.billingStreet = installationAddress;
        paymentMethod.billingCity = this.system.installationAddressCity;
        paymentMethod.billingState = this.system.installationAddressState;
        paymentMethod.billingPostalCode = this.system.installationAddressZipCode;
    } else {
        paymentMethod.billingStreet = this.paymentMethodForm.value['address']['street'];
        paymentMethod.billingCity = this.paymentMethodForm.value['address']['city'];
        paymentMethod.billingState = this.paymentMethodForm.value['address']['state'];
        paymentMethod.billingPostalCode = this.paymentMethodForm.value['address']['zip'];
    }

    this.isLoading = true;

    this.billingAndPaymentsService.savePaymentMethod(paymentMethod).then(result => {
        this.isLoading = false;
        return this.saved.emit(result);
    }).catch(() => {
        this.isLoading = false;
        this.showError = true;
    });

// this.paymentMethodForm.get('card-number').enable();
}

enablePaymentMethod(){

//this.paymentMethodForm.get('card-number').enable();
}

cancel() {
   //  console.log('this.paymentMethodForm.getcard-number.enable():', this.paymentMethodForm.get('card-number').enable());  --NOT Working---
   // this.paymentMethodForm.get('card-number').enable();
//console.log('this.paymentMethodForm.getcard-number.Afterenable():', this.paymentMethodForm.get('card-number').enable());
    this.canceled.emit();
}


ngOnChanges(changes: any): void {
    if (changes.paymentMethod) {
        this.paymentMethodForm.reset();
     this.paymentMethodForm.controls['card-number'].disable({ emitEvent: false });
     this.paymentMethodForm.controls['card-name'].disable({ emitEvent: false });
       this.enableCreditCardInputs();
        this.patchPaymentMethodForm(changes.paymentMethod.currentValue);
        if (changes.paymentMethod.currentValue) {
            this.paymentMethodForm.patchValue({
                useInstallationAddress: false,
                save: this.alwaysSave,
               
            });
            if (changes.paymentMethod.currentValue.id) {
                for (let prop in this.paymentMethodForm.controls) {
                    if (this.paymentMethodForm.controls.hasOwnProperty(prop) && this.paymentMethodForm.controls[prop] instanceof FormControl) {
                        if (prop !== 'useInstallationAddress' && prop !== 'save' && !prop.startsWith("address."))
                            this.paymentMethodForm.controls[prop].disable();
                    }
                }
            }
        } else {
            this.paymentMethodForm.patchValue({
                useInstallationAddress: false,
                save: this.alwaysSave,
                
            });
        }

        this.toggleAddressControls();
    }
}

}`

HTML part Child Component
@{
Layout = "_AddPaymentLayout.cshtml";
ViewBag.PaymentMethodTypeClass = "add-card-component";
}

Credit Card Number
Credit Card Number is required. Credit Card Number is invalid.
Name on Card
Name on Card is required.
</div>
******************************************* **MAIN HTML** `
@*"collapse.oneTimePayment = !collapse.oneTimePayment " ;showCancel=false;null*@

One Time Payment

Credit Card

`
@RPGillespie6

This comment has been minimized.

Copy link
Contributor

commented Mar 21, 2018

Why is this issue closed? Is this fixed in production builds now? Doesn't seem like it...

varghesethomas69 added a commit to varghesethomas69/myrecipe-book-app that referenced this issue Apr 13, 2018

fixed compile issue
ERROR in src\app\recipes\recipe-edit\recipe-edit.component.html(65,13): : Property 'controls' does not exist on type 'AbstractControl'.
FIX: angular/angular-cli#6099
@keego

This comment has been minimized.

Copy link

commented May 22, 2018

Running Angular 5.2.3 and was having the same problem. I have a nested FormGroup i.e.

// simplified
this.deviceForm = this.formBuilder.group({
  deviceName: '',
  advancedOptions: this.formBuilder.group({
    bridgeUrl: 'wss://api.my.site:443',
  }),
})
// this.deviceForm: FormGroup
// this.deviceForm.controls.advancedOptions: AbstractControl
// ^^ should really be type FormGroup
// this.deviceForm.controls.advancedOptions.controls.bridgeUrl
// ^^ ERROR 'controls' doesn't exist on type 'AbstractControl'

I found a few ways to get around this (thanks to y'all posting here). Assuming we have:

this.deviceForm.controls.advancedOptions.controls.bridgeUrl

We can:

1. Use .get():

this.deviceForm.get('advancedOptions')!.get('bridgeUrl')!
// Note the '!'s to tell TS to assume `get` result is non-null

2. Cast

(<FormGroup> this.deviceForm.controls.advancedOptions).controls.bridgeUrl

3. Use a custom class

// Define AbstractFormGroup
interface AbstractFormGroup extends FormGroup {
  controls: {
    [key: string]: AbstractControl & FormGroup & AbstractFormGroup,
  }
}
export class ... {
  deviceForm: AbstractFormGroup
}

// Note: This makes nested form groups (a.controls.b.controls.c... etc.)
// acceptable by the compiler, however this exposes both AbstractControl
// and FormGroup properties on all controls, so you can hit runtime errors
// if you try to use FormGroup properties when your control is just an
// AbstractControl and vice versa.

I ended up going with 1 as I think it's the cleanest

kcrutcher pushed a commit to kcrutcher/benefitsCalculator-angularClient that referenced this issue Jul 8, 2018

@mpro7

This comment has been minimized.

Copy link

commented Sep 20, 2018

This worked for me:

form.get('passwords').get('confirmPassword').dirty

@borriej

This comment has been minimized.

Copy link

commented Oct 1, 2018

This worked for me:

form.get('passwords').get('confirmPassword').dirty

This is not allowed by angular-tslint, because functions may fire multiple times

@babtsoualiaksandr

This comment has been minimized.

Copy link

commented Oct 13, 2018

Что работает для меня (даже используя флаг --prod), вместо использования элементов управления в FormArray я использую значение :
*ngFor="let item of myForm.get('items').value"

Спасибо!!! Всё работает!!!

@imvikaskohli

This comment has been minimized.

Copy link

commented Dec 13, 2018

In my case only ng build --prod was failing with -
Property 'controls' does not exist on type 'AbstractControl'

I changed

<div *ngFor="let item of myForm.controls['keyName'].controls;let indx=index;let lst=last;" >

to

HTML:-
<div *ngFor="let item of getControls(myForm, 'keyName');let indx=index;let lst=last;" >
TS File:-

getControls(frmGrp: FormGroup, key: string) {
  return (<FormArray>frmGrp.controls[key]).controls;
}

It worked for me!

@anikets43

This comment has been minimized.

Copy link

commented Jan 1, 2019

CLI doesn't complain when ['controls'] property accessor is used.

Below worked for me

 <div formArrayName="formArray" *ngFor="let item of form.get('formArray')['controls']; let i = index;">
....

</div>
@StarpTech

This comment has been minimized.

Copy link

commented Jan 12, 2019

Please reopen the issue still occurs in Angular 5.2.0

@ebinmanuval

This comment has been minimized.

Copy link

commented Feb 13, 2019

use safe navigation operator ?
change:
myForm.get('myField').controls

to:
myForm.get('myField')?.controls

anderuraga added a commit to ipartek/java_2018_0554 that referenced this issue Mar 4, 2019

@mhardaniel

This comment has been minimized.

Copy link

commented Mar 9, 2019

for validation errors use...

<span *ngIf="f.YOUR_FORM_KEY.controls.YOUR_FORM_KEY.errors?.YOUR_FORM_VALIDATION">YOUR_FORM_KEY is YOUR_FORM_VALIDATION</span>

eg.

<span *ngIf="f.name.controls.name.errors?.required">Name is required</span>

ts file

get f(): any {
    return this.userForm.controls;
}
@samuelkavin

This comment has been minimized.

Copy link

commented May 12, 2019

This solution works for me
myForm.get('<formGroupName>').get('<formControlName>').hasError('required')

@KinjalDodiyaTechifysolutions

This comment has been minimized.

Copy link

commented May 30, 2019

try this, it works for me
*ngFor="let item of formGroup?.get('timings')?.controls; let i = index;"

@anonymous1983

This comment has been minimized.

Copy link

commented May 30, 2019

<ng-container [formGroup]="providerService.providerFG">
  <ng-container formArrayName="contentSites" *ngFor="let site of providerService.providerFG.get('contentSites').value; let i = index">
    <ng-container [formGroupName]="i">
      <input formControlName="id">
      <app-content-site [idSite]="route.snapshot.paramMap.get('id')" [index]="i" *ngIf="isSiteActivated() && route.snapshot.paramMap.get('id') === providerService.providerFG.get(['contentSites', i]).get('id').value"></app-content-site>
    </ng-container>
  </ng-container>
</ng-container>
@benneq

This comment has been minimized.

Copy link

commented Jun 3, 2019

@anonymous1983 Using *ngFor="... form.get('foo').value" instead of *ngFor="... form.get('foo').controls" does fix the template error, but it introduces reinitialization of the components within the array. This means, within your nested form you can only type one character, then it loses focus, because the nested component is getting recreated (ngOnInit is getting called for every key stroke).

My form looks like this:

form = this.fb.group({
  foo: this.fb.array([{ x: '', y: '' }]),
});

Though i'd go for *ngFor="... form.get('foo')['controls'] to prevent the template error:

<form [formGroup]="form">
  <ng-container formArrayName="foo">
    <div *ngFor="let item of form.get('foo')['controls']; let i = index">
      <app-custom-control-value-accessor [formControlName]="i"></app-custom-control-value-accessor>
    </div>
  </ng-container>
</form>
@Vreyesm

This comment has been minimized.

Copy link

commented Jun 29, 2019

Got it!

Looked at the docs - FormArray

The FormArray class contains the controls property.

get formData() { return <FormArray>this.passwordForm.get('Data'); }

Thanks @Thisen, without you help it would've taken longer.

I'm using angular 8 at this moment and I've used
get formData() { return this.passwordForm.get('Data') as FormArray; }

@cluzier

This comment has been minimized.

Copy link

commented Jul 16, 2019

La solucion mas facil es: formGroup.controls['any']['controls'].

thank you, gracias, this helped me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.