1

I'm trying to make a reactive form that displays a checkbox list where each item in the list is an item from an array. I am trying to make it so I can select as many items from the array using this checkbox list.

I have tried using FormArrays, reading multiple articles and StackOverflow answers on the topic but could not figure it out and have gotten very confused as different sources offered different solutiuons.

Here is my component.ts file:

export class ItemSelectorComponent implements OnInit {

  public list: Array<ItemData>;
  public collectionForm: FormGroup;

  constructor(
    private db: DatabaseService,
    private fb: FormBuilder
  ) { }

  async ngOnInit(): Promise<void> {
    await this.getList();

    this.collectionForm = this.fb.group({
      name: [null],
      items: [null] //I have tried here new FormArray([]) and this.fb.array(...) but to no avail
    });
  }

  async getList() { //Sets the value of the list to response from the backend.
    var res = await this.db.getList();
    if (res.status == 200) {
      this.list = res.body;
    } else {
      console.log(`List Status Code ${res.status}.`);
      this.list = [];
    }
  }

  //Form Functions

  submit() {
    console.log(this.collectionForm.value);
  }

}

and my component.html

<form [formGroup]="collectionForm" (ngSubmit)="submit()">
  <mat-form-field appearance="fill" required>
    <mat-label>Collection Name</mat-label>
    <input matInput formControlName="name">
  </mat-form-field>

  <br>

  <!-- Implement here some sort of ngFor that loops over list and has checkbox inputs -->

  <br>
  <button mat-raised-button color='primary'>Submit</button>
</form>

1 Answer 1

3

Well, you need to do a few things.

  1. Initialize form group before server side call with empty FormArray
  2. In your async getList() method dynamically push new items to your form array.
  3. Render form array items dynamically

After you get the list from server push new items :

const items = this.form.get("items") as FormArray;
    this.list.forEach(r => {
      items.push(
        this.fb.group({
          id: r.id,
          checked: r.checked
        })
      );
    });

Then in your form render form array items dynamically :

 <div *ngFor="let item of form.get('items').controls;let i = index" [formGroup]="item">

    <div>
      Check <input type="checkbox" formControlName="checked">
    </div>

  </div>

Stackblitz

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for taking the time to answer this. I will test this and let you know in the morning.
Sir, you are a legend.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.