I get this error:
There are no form controls registered with this array yet. If you're using ngModel, you may want to check next tick (e.g. use setTimeout).
When using this code:
public settingsForm: FormGroup = this.fb.group({
collaborators: this.fb.array([]),
rsvp: this.fb.group({
latestDate: ['', [Validators.required]],
latestTime: ['', [Validators.required]],
guestLimit: ['', [Validators.required]],
isRSVPOpen: false,
isGuestPlusOne: false,
isAutoApproveToGuestlist: false,
isOnlyFacebookRSVP: false,
isBirthdayAndPhoneRequired: false
}),
tickets: this.fb.group({
info: this.fb.group({
closingDate: '',
closingTime: ''
}),
types: this.fb.array([])
})
});
Inside ngOnInit
:
this.eventSubscription = this.af.database.object('/events/' + this.eventId)
.filter(event => event['$value'] !== null)
.subscribe((event: IEvent) => {
const settings: ISettings = event.settings;
const collaborators: ICollaborator[] = settings.collaborators;
const rsvp: IRSVP = settings.rsvp;
const tickets: ITickets = settings.tickets;
this.settingsForm.setValue({
collaborators: collaborators || [],
rsvp: rsvp,
tickets: {
info: tickets.info,
types: tickets.types || []
}
});
}
);
When collaborators
contains a value, i.e it's not undefined
, null
or empty []
, something like:
[
{
email: 'foo@bar.com',
role: 1
},
{
email: 'baz@bar.com',
role: 2
}
]
Then the app crashes on the setValue
line in the eventSubscription
.
I cannot figure out why this is happening.
Any ideas?
Initialize the form array with the control. That would resolve the issue. See Reactive Forms guide if you need to know how to do that. If you are using ngModel
it would probably worth to remove it.
Before calling setValue(data)
on a FormGroup or FormArray, the FormGroup or FormArray must have the exactly same structure of the data
. Only the structure matters, the value in the FormGroup or FormArray will be replaced by data
.
Example, if your data is
let data = [ {a: 1, b:2}, {a: 3, b: 4} ]
Then the FormArray must has 2 FormGroups and each FormGroup must has one FieldControl called a
and one called b
. You can do something like this:
let fa = this.formBuilder.array([
this.formBuilder.group({a: 0, b:0}),
this.formBuilder.group({a: 0, b:0})
])
fa.setValue(data)
If your data is of more complex structure, the FormArray needs to have the same complex structure.
You have to build your form OnInit before setting its value. Try something like this :
settingsForm: FormGroup;
buildForm(): void {
settingsForm: FormGroup = this.fb.group({
//content of settingsForm
})
}
ngOnInit() {
this.buildForm();
this.eventSubscription = this.af.database.object('/events/' + this.eventId)
//...
this.settingsForm.setValue({ //you can try .patchValue to set only available value
//...
})
}
I think this code will help
import { FormArray, FormBuilder, FormGroup} from '@angular/forms';
export class SomeComponent implements OnInit {
consutructor(public fb:FormBuilder) { }
public buildcollaboratorsGroup(fb:FormBuilder):FormGroup {
return fb.group({
email:'',
role:''
});
}
ngOnInit() {
public settingsForm: FormGroup = this.fb.group({
collaborators:this.fb.array([this.buildcollaboratorsGroup(this.fb)])
});
this.setFormArrayValue();
}
// I am trying set only one value if it's multiple use foreach
public setFormArrayValue() {
const controlArray = <FormArray> this.settingsForm.get('collaborators');
controlArray.controls[0].get('email').setValue('yourEmailId@gmail.com');
controlArray.controls[0].get('role').setValue(2);
}
// I am trying remove only one value if it's multiple use foreach
public removeFormArrayValue() {
const controlArray = <FormArray> this.settingsForm.get('collaborators');
controlArray.removeAt(0);
}
}