Juri Strumpflohner

Juri is a full stack developer and tech lead with a special passion for the web and frontend development. He creates online videos for Egghead.io, writes articles on his blog and for tech magazines, occasionally speaks at conferences and holds training workshops.

Learn how easy it is to create dynamic, reactive forms with Angular

Heared about reactive Angular forms? Maybe even about dynamic forms? Never tried because you think it’s too complicated to setup and an overkill for your common use cases? Let me try to help you learn about how easy it is to setup dynamic forms with Angular.

Quite mixed results. Those who tried actually liked it, but there seem to be a lot of people who were either dissatisfied or didn’t try yet. The goal of this article is to help those get started easily.

Egghead.io - Video Course

If you’re too lazy to read and would rather like to walk through all this stuff step by step with me, then definitely check out my Egghead course on “Create Dynamic Forms with Angular”.

Template driven and reactive forms

Angular has two different types of forms you can choose from, template driven and reactive forms (also called model driven) . There are a lot of articles out there already (including a very rough intro I’ve written last year) about the difference between the two.

At a very high level, very generalized we could say that…

template driven forms - you start and do most of the work in the Angular template by adding bindings with custom directives; Angular creates the according form control objects behind the scenes

reactive forms - you start in your component class, by creating your form programmatically before then binding the resulting object to the template; you’re in charge/control of every single step; you have observable streams on changes of the form elements etc..

Why even create Dynamic Forms

Dynamic forms can be a very powerful instrument. Imagine you have a varying object model, where the user itself can decide how many fields there are or add additional ones. Think of questionaire interfaces such as Google Forms where you wouldn’t know about how many fields and which kind of fields the user of the form is about to define. There are a lot of interesting and valid use cases.

But now let’s get to the meat. In this example we’ll follow the reactive forms approach.

Our API

In order to be able to create a dynamic form, we need to have a proper way of describing the structure of our form as well as of our data we want to get out of it in the end.

This is just one way it could look like which I’ve created purposefully just for this tutorial. There are potentially many ways of how such API could look like and it may largely depend on the type of use case and application.

This API could be directly exposed by some backend or defined within our application. That’s up to you. In this example here I simply created an object that represents it.

the name itself represents the property of our Person model. That’s the property I expect the form to fill with the value the user inputs;

the actual value of the property name which gets databound to the form input field. This could be the data which is already present in our model/store/DB, or simply a default value;

then there is a label which is simply the one that gets rendered as the input field <label>;

the type which indicates which HTML input field should be rendered (text, radio, select,…);

and finally a set of validators to be applied to our form input field.

Reactive Forms Refresher

To start we should first take a closer look at how we would bind our simple example of the Person’s name property using Angular’s reactive form approach. So in our component class we create a new FormGroup with a FormControl for our name property.

Not this is the extended form as we will need it later. For a shorter variant, inject the FormBuilder

Then, our component template needs to bind the the FormGroup we just created (form member variable) using the [formGroup] directive and then the formControlName directive for associating our nameFormControl to the correct HTML input field.

Rendering the form dynamically

Great, that was easy. Now let’s make it dynamic. ! To do so, we create a new Angular component called dynamic-form.component.ts which is responsible for rendering a dynamic form based on the @Input he gets.

This new structure is more suitable for iterating over it and to setup the proper form. We use Object.keys(..) to iterate over all of the properties coming from the @Input and store the result in a member variable objectProps of our component (which we’ll access later from within our template).

Note, we iterate over our dataObject which again comes from our component @Input. For each property we create a new FormControl, passing in the property value this.dataObject[prop].value (or an empty string) and we map it to the formGroup using the property name as key formGroup[prop]. formGroup here is just a plain normal JavaScript object which we then assign to our form member variable of our component:

this.form = new FormGroup(formGroup);

Create Form Validators

You might have seen that when creating the FormControl I also invoked a this.mapValidators(...) function passing in the validators specified in the validation property of our dataObject coming from the @Input. That function is actually quite simple. All it does is to take the defined validation and map it to a proper form validator instance:

Render the HTML

We’re all set now. We have our form: FormGroup object as well as the array of properties to map stored in the objectProps member. We can now use those two in our template to construct the actual HTML form.

Next we iterate over the objectProps to make sure we create an according form input field for all our object’s properties. Here for instance we should already see the labels with the specified value being rendered.

Note how we use an ngSwitch statement on the type property which defines which kind of input field we need. We then specify a ngSwitchCase="'text'" to define the case for text inputs. By doing so we also bind the formControlName accordingly as well as the type and id property of the HTML input field.

Final, Running Example

Great! You did it! Here’s our running example using the amazing StackBlitz editor. Hint: you can modify the structure and see the form dynamically reflect the change

Conclusion

As you have seen, creating a simple dynamic form using the reactive approach in Angular is extremely easy. Of course in a real world scenario things might get more complex due to the complexity of your forms or your application requirements. You can definitely code the dynamic form yourself as we have learned in this article. Otherwise there’s ng-formly which can help you automate a big part.