Reactive Forms Benefits: Nested Form Groups
Tags: angular, reactiveforms
Published: 2020-07-18 04:38:50

---
title: Reactive Forms Benefits: Nested Form Groups
published: true
date: 2020-07-17 06:00:00 UTC
tags: angular,reactiveforms
canonical_url: https://www.prestonlamb.com/blog/reactive-forms-benefits-nested-form-groups
---

## [tldr;](#tldr)

Many times when trying to collect data from users, the forms can get complex. It can be hard to know how to collect the data, and do so in the simplest manner, but I’ve found that reactive forms in Angular make it easier than I thought. In this post, we’ll look at an example I recently came upon at work and how easy it was to solve with reactive forms.

## [Background](#background)

I work for a health insurance company, and I needed to collect some information about a member and the people on their policy. Part of the requirement for the form was to select checkboxes next to each person on the policy to say if the information entered applied to them. I started thinking about how to go about this, knowing I couldn’t hard-code anything because every policy is different. I had an Observable that gave me an array of the people on the policy, so I knew I could loop over that array to output the checkboxes, but I didn’t know how to get the values from those checks into the form.

## [Solution](#solution)

The solution turned out to be pretty simple. All I needed to do was to make one of the controls in my `FormGroup` have the value of another `FormGroup`. It ended up looking like this (in part):

```js
this.memberService.memberFamilyArray$
  .pipe(
    tap((family: Person[]) => {
      this.informationForm = this._formBuilder.group({
        affectedPolicyMembers: this._formBuilder.group(
          family.reduce((group: any, person: Person) => {
            group[person.id] = null;
            return group;
          }),
        ),
      });
    }), 
  )
.subscribe();
```

What’s happening here is that the top level `form` has an attribute `affectedPolicyMembers`. The value of that control is another `FormGroup`. The `FormGroup` is created by using the `reduce` method on the `family` array. Each family member has an `id`, so I added each ID as a key on the object and set the initial value to null. This got the form set up properly, but the next step was how to output the form controls in the HTML. Here’s what I ended up doing:

```html
<form [formGroup]="informationForm">
  <div formGroupName="affectedPolicyMembers">
    <label *ngFor="let member of memberFamilyArray$ | async">
      <input [formControlName]="member.id" type="checkbox" /> 
    </label>
  </div>
</form>
```

This looks pretty straight-forward as far as reactive forms go, but notice that on the div right below the `form` element there’s an attribute called `formGroupName`. That’s where the `affectedPolicyMembers` attribute from the `informationForm` goes. Then inside that div you can use the nested form group’s attributes. In this case, there’s one attribute for each member on the policy, and the key is the member’s ID.

## [Conclusion](#conclusion)

This would have been a lot harder to correctly capture the information without a reactive form. Not only was I able to capture the data just by boxes being checked, I was also able to add [custom validation](/blog/reactive-forms-benefits-validators) to the `affectedPolicyMembers` group. Reactive forms in Angular have a lot of benefits, and nested `FormGroup`s are one of those many benefits.