Reputation: 390
I don't know why but my placeholder work perfectly. So I can see the name of my music, but if I want to use my formControleName
my error is : Cannot find control with path: musics -> name
This is my form :
this.musicsForm = new FormGroup({
musics: new FormArray([
new FormControl(new Music('Musique 1', null, null)),
new FormControl(new Music('Musique 2', null, null)),
]),
});
And my object is like that :
export class Music {
_id: string;
name: string;
fileUrl: string;
feat: string; // i don't use it right now
index: number; // i don't use it right now
constructor(name: string, fileUrl: string, feat: string, index?: number) {
this.name = name;
this.fileUrl = fileUrl;
this.feat = feat;
this.index = index;
}
}
And this is my HTML :
<form [formGroup]="musicsForm" cdkDropList class="col-md-11 px-0" (cdkDropListDropped)="drop($event)">
<class="example-box" *ngFor="let m of musicsForm.get('musics').controls; let i = index" cdkDrag>
<div class="item row my-4 w-100" [formGroupName]=i>
...
<div class="col-md-4 mt-1">
<input class="px-2 w-100" type="text" [placeholder]="m.value.name" formControlName="name" > // I think the bug is just here
</div>
...
</div>
</div>
</form>
Upvotes: 2
Views: 4747
Reputation: 8650
Your formArray
is an array of type formGroup
, so you need to add a formGroupName
within your ngfor
to bind each formGroup
in your formArray
. This should be placed on an HTML element which encapsulates the formControl
s within (i.e. properties in your formGroup
: name
, fileUrl
, etc. You also need to pass a formGroup
to your formGroupName
. In order to pass the entire formGroup
, you need to be looping through each element in musics.controls
not musics.value
.
Now, since we are no longer looping over musics.value
, you will not be able to access the name
value in your placeholder
using m.name
. You should use m.value.name
instead.
Edit: You will also need to update your component as you creating a formControl
when you should be creating a formGroup
. You can use FormBuilder
since it lets you generate formGroup
using the normal object syntax. It would be better to create your entire form using FormBuilder
rather than a mix of both FormBuilder
and manual FormControl
instances (creating form using new FormGroup
, new FormControl
, etc.)
this.musicsForm = this.fb.group({
musics: this.fb.array([
this.fb.group(new Music('Musique 1', null, null)),
this.fb.group(new Music('Musique 2', null, null)),
])
});
Here's how your HTML will now look.
<div cdkDropList class="col-md-11 px-0" (cdkDropListDropped)="drop($event)" formArrayName="musics">
<div class="example-box" *ngFor="let m of musicsForm.get('musics').controls; let i = index" cdkDrag>
<div class="item row my-4 w-100" [formGroupName]="i">
<!-- Define all formControlNames within your formGroup within this div -->
...
<div class="col-md-4 mt-1">
<input class="px-2 w-100" type="text" [placeholder]="m.value.name" formControlName="name">
</div>
...
</div>
</div>
</div>
Check out this example on how to implement formArray
correctly
Upvotes: 3
Reputation: 29305
add this in:
<div class="example-box" *ngFor="let m of musics.value;let i = index" [formGroupName]="i" cdkDrag>
your form array is an array of groups, and their group name is the index in that array. You need to tell angular that you want the 'name' control, and at which index you want it. right now you're just saying I want the 'name' control of the form array 'musics' which doesn't exist, it only exists at indexes.
Upvotes: 0