Mackelito
Mackelito

Reputation: 4421

ControlValueAccessor with FormArray in Angular

How can I pass down the formArray to child article component?

The article component does not have a formgroup (defined in parent) and I get an error: Error: formArrayName must be used with a parent formGroup directive

ParentComponent

// structure:
form = new FormGroup({
    articles: new FormArray([])
}
<articles-list [articles]="articles" formArrayName="articles"></articles-list>
<article [formControlName]="article.id" *ngFor="let article of articles" [article]="article"></article>

form structure should be:

parent {
 articlesList: article[]
}

Upvotes: 0

Views: 1986

Answers (2)

Ross
Ross

Reputation: 126

Make sure to nest your articles-list component inside of a [formGroup].

<form [formGroup]="form">
    <articles-list [articles]="articles" formArrayName="articles">
    </articles-list>
</form>

    
<!-- You can try something like this - just incorporate your custom components ->
<form [formGroup]="form">
    <div formArrayName="articles">
        <div *ngFor="let child of form.controls.articles.controls; let i=index;">
            <div class="form-group stagger" formGroupName="{{i}}">
                <input formControlName="sampleField" />
            </div>
        </div>
    </div>
</form>

Upvotes: 1

Eliseo
Eliseo

Reputation: 57929

when pass a FormControl/or FormArray to a component, the component can implements ControlValueAssesor -the is like another input-, or we can pass the FormControl/FormArray itseft -nor formArray name-.

When we use an FormArray is advisable use a getter in .ts

articlesFormArray get()
{
    return this.form.get('articles') as FormArray
}

So, you can pass as argument the formArray

<articles-list [myFormArray]="articlesFormArray"></articles-list>

And in articles-list

@Input() myFormArray:FormArray

//create a new getter to get the FormGroup of the formArray, 
get formGroup(i)
{
    return myFormArray.at(i) as FormGroup
}

<div *ngFor="let control of myFormArray.controls;let i=index">
     <div [formGroup]="formGroup(i)">
          <input formControlName="articleId">
     </div>
</div>

Is our children mannage a FormGroup, you can pass the formGroup, imagine in the example before a children-component

@Input('group') form:FormGroup //<--the name is group, but the variable "form"
                               //it's only show a characteristic of Inputs
<div [formGroup]="form">
  <input formControlName="articleId">
</div>

We can replace use in articles-list.html

<div *ngFor="let control of myFormArray.controls;let i=index">
     <children-component [group]="formGroup(i)">
</div>

Upvotes: 1

Related Questions