0

I have a form that contains a list of checkboxes for the user to check and then when the user submit the form, it should submit the list of checkboxes as an array of objects. Instead, I'm getting nothing.

What I'm getting in the console: {fruits: Array[0]}

What I expected: {fruits: Array[1]} // The numbers of array depends on the checkbox checked

Here is a stackblitz for an example

Alan S
  • 93
  • 1
  • 9

2 Answers2

0

You have done all except form initialization

myForm: FormGroup = this.initModelForm();

Full code is: I am console logging the formArray value

import { Component } from '@angular/core';
import { FormGroup, FormArray, FormControl, FormBuilder } from '@angular/forms';

export interface Fruit {
  uid: string;
  name: string;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent   {
public checks = [
  {description: 'descr1', value: 'value1'},
  {description: "descr2", value: 'value2'},
  {description: "descr3", value: 'value3'}
];

myForm: FormGroup = this.initModelForm();

constructor(
  public _fb: FormBuilder
) { }

initModelForm(): FormGroup{
  return this._fb.group({
    otherControls: [''],
    myChoices: new FormArray([])
  })
}

onCheckChange(event) {
  console.log(event);
  const formArray: FormArray = this.myForm.get('myChoices') as FormArray;

  /* Selected */
  if(event.target.checked){
    // Add a new control in the arrayForm
    formArray.push(new FormControl(event.target.value));
  }
  /* unselected */
  else{
    // find the unselected element
    let i: number = 0;

    formArray.controls.forEach((ctrl: FormControl) => {
      if(ctrl.value == event.target.value) {
        // Remove the unselected element from the arrayForm
        formArray.removeAt(i);
        return;
      }

      i++;
    });
  }
  console.log(formArray.value);
}
}
Sumeet
  • 574
  • 5
  • 5
0

It's an aproach like Netanel Basal (only change the submit function). The things goes more fluid if we think in a Form who value can be like e.g.

{
  "otherControls": "",
  "myChoices": [
    false,
    true,
    false
  ]
}

Well, we don't want this ugly data, but we can, in submit write some like

submit(myForm) {
    if (myForm.valid) {
      const value = { ...myForm.value };
      value.myChoices = this.checks
        .filter((x, index) => myForm.value.myChoices[index])
        .map(x => x.value);
      this.result = value;
    }
  }

And "result" will be,e.g.

{
  "otherControls": "",
  "myChoices": [
    "value2"
  ]
}

Well, its true that we are complex the "submit", but in another hand, our form becomes like

<form *ngIf="myForm" [formGroup]="myForm" (submit)="submit(myForm)">
  <div formArrayName="myChoices">
  <div *ngFor="let choice of myForm.get('myChoices').controls; let i=index" class="col-md-2">
    <label>
      <input type="checkbox" [formControlName]="i">
      {{checks[i].description}}
    </label>
  </div>
  </div>
  <button type="submit">submit</button>
</form>

NOT externals function, not fight agains remove at push,etc Well, the only is create the form like

initModelForm(): FormGroup {
    return this._fb.group({
      otherControls: [""],
      myChoices: new FormArray(this.checks.map(x => new FormControl(false)))
    });
  }

See stackblitz

Eliseo
  • 50,109
  • 4
  • 29
  • 67