This is the second in a series of articles on building Angular forms using the Reactive Forms technique. I recommend that you read Part 1 before continuing as this article builds upon topics introduced in Part I. In order to illustrate various aspects of Reactive Forms, I have created a small demo application which you can download and run on your machine as you follow along. In this article, I will discuss how to add a set of form controls dynamically. Our form contains a section where you can add items dynamically. Clicking on the ‘+’ button will add a new row of controls.

To do this, we will take the help of the FormArray  API. First lets take a look at the relevant code in the component class( edit-consignment.component.ts ).

The component constructor calls the createForm() method which creates the form model as discussed in Part I of this series. Now let’s focus on this line.

Here we are using the FormBuilder API to add an array of FormGroups as a child of the consignmentForm object which manages the value and state of the HTML form. As shown below the createItem() method creates and returns a FormGroup containing all the form controls that we want to add dynamically.

In the component template( edit-consignment.component.html) we have the following code.

We use the ngFor directive to iterate over all the FormGroups that have been added to the ‘items’ FormArray. Initially when the page is shown, a single row is displayed as we have initialized the FormArray with a single FormGroup object created by the createItem() method. Note that for each FormGroup in the items array, we capture the array index in the variable “i” and assign this as the formGroupName of the div representing each group of repeated controls. We can refer to the ‘i’-th item(FormGroup) in the items array  using

Lets now look at the code which is called when the user clicks on the ‘+’ button. In our template we bind the ‘click’ event of the button to the addItem() method in the component class.

The relevent code in the addItem() method is shown below. We simply get a handle to the ‘items’ FormsArray object and push in a new FormGroup returned by the createItem method.

This is enough to allow us to dynamically add a group of controls to our form. Going back to the requirements discussed in Part I,

  • For each item the user needs to choose the tea type and enter the number of containers and weight per container. The total item weight should be calculated based on the number of containers and weight of each container.

So we need a way to update the total weight of each item once the user has entered the no. of containers and weight of each container. To achieve this we take the help of the valueChanges property of FormControl.  This is an rxjs Observable that you can subscribe to if you need to listen for a change in value( by the user or programatically) of a form control.  Let us take a look at the relevant code in the createItem() method.

The above code listens for changes in value of no. of containers and weight per container of each item and invokes the updateTotalWeight() method.

The updateTotalWeight() method simply picks up the values of the ‘noOfContainers’ and ‘weightPerContainerinKgs and multiples the 2 values to calculate the total weight. To display the total calculated weight in the totalWeight HTML element , we use the  setValue method on the form control.

This concludes Part 2 of this series. In this part we have have covered the following topics :-

  • Using the FormArray API to add a group of form controls dynamically to a form.
  • Listening for a change in the value of a form control and performing some action.

In the next part of the series we will cover custom validations.

Reactive Forms in Angular – A Practical Guide (Part 2)
Tagged on: