I have a list of interests i am getting from the backend. I want a user to be able to select the interests they want. I will store only the interests they checked in the DB and pre-populate when they load the page. But first i need to get these interests the user has selected.
interest.component.ts
export class InterestsComponent implements OnInit { interestFormGroup : FormGroup interests:any; selected: any; constructor(public interestService: InterestService, private formBuilder: FormBuilder, ) { } ngOnInit() { this.interestFormGroup = this.formBuilder.group({ interests: this.formBuilder.array([]) }); this.interestService.all().subscribe((res) => { this.interests = res; }); } change() { console.log(this.interestFormGroup.value); } }
interest.component.html
<div id="interest"> <div class="interest-list"> <form [formGroup]="interestFormGroup"> <div *ngFor="let interest of interests" > <mat-checkbox class="example-margin" formNameArray="interests" (change)="change()">{{interest}}</mat-checkbox> </div> </form> </div> </div>
In my console.log on the change event it shows there is no values being added to the interests array within the interestFormGroup. Even tho the checkboxes are checked.
The MultiSelect has built-in support to select multiple values through checkbox, when mode property set as CheckBox . To use checkbox, inject the CheckBoxSelection module in the MultiSelect.
A FormGroup aggregates the values of each child FormControl into one object, with each control name as the key. It calculates its status by reducing the status values of its children. For example, if one of the controls in a group is invalid, the entire group becomes invalid.
If checkbox will be checked then ng-readonly will get TRUE value and TextBox will be converted into Read-Only TextBox. If checkbox will be unchecked then ng-readonly will get FALSE value and Read-Only TextBox will be converted into again Read-Write textbox.
You should add controls to FormArray
manually like:
this.interests = res; const formArray = this.interestFormGroup.get('interests') as FormArray; this.interests.forEach(x => formArray.push(new FormControl(false)));
then change template as follows:
<form [formGroup]="interestFormGroup" (ngSubmit)="submit()"> <ng-container formArrayName="interests"> <div *ngFor="let interest of interests; let i = index" > <mat-checkbox class="example-margin" [formControlName]="i"> {{interest}} </mat-checkbox> </div> </ng-container> <button>Submit</button> </form>
And when you will submit form you need to transform FormArray
values to your desired result:
submit() { const result = Object.assign({}, this.interestFormGroup.value, { interests: this.interests .filter((x, i) => !!this.interestFormGroup.value.interests[i])}); console.log(result); }
Alternative solution is listen change
event and manually add and remove value to FormArray
:
<div *ngFor="let interest of interests; let i = index" > <mat-checkbox class="example-margin" (change)="onChange($event)" [value]="interest">{{interest}}</mat-checkbox> </div> onChange(event) { const interests = <FormArray>this.interestFormGroup.get('interests') as FormArray; if(event.checked) { interests.push(new FormControl(event.source.value)) } else { const i = interests.controls.findIndex(x => x.value === event.source.value); interests.removeAt(i); } }
Stackblitz example
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