I have a form where I'd like the user to edit which magazine subscriptions he'd like to receive. The code is as follows:
Component:
export class OrderFormComponent {
subscriptions = [
{id: 'weekly', display: 'Weekly newsletter'},
{id: 'monthly', display: 'Monthly newsletter'},
{id: 'quarterly', display: 'Quarterly newsletter'},
];
mySubs = [
this.subscriptions[1]
]
order = new FormGroup({
subs: new FormArray(this.mySubs.map(sub => new FormControl(sub)), Validations.required) //Lost at this part
});
}
Template:
<form [formGroup]="order">
<div formArrayName="subs">
<label>Sign me up for newsletters</label>
<p *ngFor="let s of subscriptions; let i=index">
<input type="checkbox" [value]="s.id" [formControlName]="i" /> {{ s.display }}
</p>
</div>
<div>
<input type="checkbox" formControlName="agree" /> I agree to the terms and conditions.
</div>
{{ order.value | json }}
When I run the app, three checkboxes are displayed but only one is checked (the wrong one at that). The one that's checked has a label while the others don't.
What am I doing wrong here?
Ok so I finally figured it out.
In my component I have:
// The order retrieved from the server
subscription = {
schedules: [{id: 'weekly', display: 'Weekly update'}],
}
//The FormGroup element
this.subscriptionForm = new FormGroup({
//Here I fill up a FormArray with some FormControls initialized to the
//currently selected schedules
schedules: new FormArray(this.subscription.schedules.map(schedule => new FormControl(schedule)), Validators.minLength(1))
});
In the view I have:
<div>
<label>Frequency</label>
<p *ngFor="let schedule of viewData.schedules">
<input type="checkbox"
[checked]="subscription.schedules.includes(schedule)"
(change)="changeSchedules(schedule)"> {{ schedule.display }}
</p>
</div>
And here is the changeSchedules()
method in the class:
changeSchedules(schedule: any) {
var currentScheduleControls: FormArray = this.subscriptionForm.get('schedules') as FormArray;
var index = currentScheduleControls.value.indexOf(schedule);
if(index > -1) currentScheduleControls.removeAt(index) //If the user currently uses this schedule, remove it.
else currentScheduleControls.push(new FormControl(schedule)); //Otherwise add this schedule.
}
Works like a charm! Form validates as expected, with no extra method needed to retrieve/consolidate the subscription array before form submission.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With